Store sensitive export options in dedicated credentials file
This commit is contained in:
parent
668cf3c66f
commit
fab160ce70
@ -704,6 +704,7 @@ void register_global_constants() {
|
|||||||
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT);
|
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT);
|
||||||
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_BASIC_SETTING);
|
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_BASIC_SETTING);
|
||||||
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_READ_ONLY);
|
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_READ_ONLY);
|
||||||
|
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SECRET);
|
||||||
|
|
||||||
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFAULT);
|
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFAULT);
|
||||||
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_EDITOR);
|
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_EDITOR);
|
||||||
|
@ -118,6 +118,7 @@ enum PropertyUsageFlags {
|
|||||||
PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 26, // For Object properties, instantiate them when creating in editor.
|
PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 26, // For Object properties, instantiate them when creating in editor.
|
||||||
PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 27, //for project or editor settings, show when basic settings are selected.
|
PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 27, //for project or editor settings, show when basic settings are selected.
|
||||||
PROPERTY_USAGE_READ_ONLY = 1 << 28, // Mark a property as read-only in the inspector.
|
PROPERTY_USAGE_READ_ONLY = 1 << 28, // Mark a property as read-only in the inspector.
|
||||||
|
PROPERTY_USAGE_SECRET = 1 << 29, // Export preset credentials that should be stored separately from the rest of the export config.
|
||||||
|
|
||||||
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR,
|
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR,
|
||||||
PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE,
|
PROPERTY_USAGE_NO_EDITOR = PROPERTY_USAGE_STORAGE,
|
||||||
|
@ -2842,6 +2842,9 @@
|
|||||||
<constant name="PROPERTY_USAGE_READ_ONLY" value="268435456" enum="PropertyUsageFlags" is_bitfield="true">
|
<constant name="PROPERTY_USAGE_READ_ONLY" value="268435456" enum="PropertyUsageFlags" is_bitfield="true">
|
||||||
The property is read-only in the [EditorInspector].
|
The property is read-only in the [EditorInspector].
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="PROPERTY_USAGE_SECRET" value="536870912" enum="PropertyUsageFlags" is_bitfield="true">
|
||||||
|
An export preset property with this flag contains confidential information and is stored separately from the rest of the export preset configuration.
|
||||||
|
</constant>
|
||||||
<constant name="PROPERTY_USAGE_DEFAULT" value="6" enum="PropertyUsageFlags" is_bitfield="true">
|
<constant name="PROPERTY_USAGE_DEFAULT" value="6" enum="PropertyUsageFlags" is_bitfield="true">
|
||||||
Default usage (storage, editor and network).
|
Default usage (storage, editor and network).
|
||||||
</constant>
|
</constant>
|
||||||
|
@ -37,7 +37,9 @@ EditorExport *EditorExport::singleton = nullptr;
|
|||||||
|
|
||||||
void EditorExport::_save() {
|
void EditorExport::_save() {
|
||||||
Ref<ConfigFile> config;
|
Ref<ConfigFile> config;
|
||||||
|
Ref<ConfigFile> credentials;
|
||||||
config.instantiate();
|
config.instantiate();
|
||||||
|
credentials.instantiate();
|
||||||
for (int i = 0; i < export_presets.size(); i++) {
|
for (int i = 0; i < export_presets.size(); i++) {
|
||||||
Ref<EditorExportPreset> preset = export_presets[i];
|
Ref<EditorExportPreset> preset = export_presets[i];
|
||||||
String section = "preset." + itos(i);
|
String section = "preset." + itos(i);
|
||||||
@ -83,16 +85,21 @@ void EditorExport::_save() {
|
|||||||
config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter());
|
config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter());
|
||||||
config->set_value(section, "encrypt_pck", preset->get_enc_pck());
|
config->set_value(section, "encrypt_pck", preset->get_enc_pck());
|
||||||
config->set_value(section, "encrypt_directory", preset->get_enc_directory());
|
config->set_value(section, "encrypt_directory", preset->get_enc_directory());
|
||||||
config->set_value(section, "script_encryption_key", preset->get_script_encryption_key());
|
credentials->set_value(section, "script_encryption_key", preset->get_script_encryption_key());
|
||||||
|
|
||||||
String option_section = "preset." + itos(i) + ".options";
|
String option_section = "preset." + itos(i) + ".options";
|
||||||
|
|
||||||
for (const PropertyInfo &E : preset->get_properties()) {
|
for (const PropertyInfo &E : preset->get_properties()) {
|
||||||
config->set_value(option_section, E.name, preset->get(E.name));
|
if (E.usage & PROPERTY_USAGE_SECRET) {
|
||||||
|
credentials->set_value(option_section, E.name, preset->get(E.name));
|
||||||
|
} else {
|
||||||
|
config->set_value(option_section, E.name, preset->get(E.name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config->save("res://export_presets.cfg");
|
config->save("res://export_presets.cfg");
|
||||||
|
credentials->save("res://.godot/export_credentials.cfg");
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExport::save_presets() {
|
void EditorExport::save_presets() {
|
||||||
@ -202,6 +209,13 @@ void EditorExport::load_config() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<ConfigFile> credentials;
|
||||||
|
credentials.instantiate();
|
||||||
|
err = credentials->load("res://.godot/export_credentials.cfg");
|
||||||
|
if (!(err == OK || err == ERR_FILE_NOT_FOUND)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
block_save = true;
|
block_save = true;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -284,22 +298,30 @@ void EditorExport::load_config() {
|
|||||||
if (config->has_section_key(section, "encryption_exclude_filters")) {
|
if (config->has_section_key(section, "encryption_exclude_filters")) {
|
||||||
preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters"));
|
preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters"));
|
||||||
}
|
}
|
||||||
if (config->has_section_key(section, "script_encryption_key")) {
|
if (credentials->has_section_key(section, "script_encryption_key")) {
|
||||||
preset->set_script_encryption_key(config->get_value(section, "script_encryption_key"));
|
preset->set_script_encryption_key(credentials->get_value(section, "script_encryption_key"));
|
||||||
}
|
}
|
||||||
|
|
||||||
String option_section = "preset." + itos(index) + ".options";
|
String option_section = "preset." + itos(index) + ".options";
|
||||||
|
|
||||||
List<String> options;
|
List<String> options;
|
||||||
|
|
||||||
config->get_section_keys(option_section, &options);
|
config->get_section_keys(option_section, &options);
|
||||||
|
|
||||||
for (const String &E : options) {
|
for (const String &E : options) {
|
||||||
Variant value = config->get_value(option_section, E);
|
Variant value = config->get_value(option_section, E);
|
||||||
|
|
||||||
preset->set(E, value);
|
preset->set(E, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (credentials->has_section(option_section)) {
|
||||||
|
options.clear();
|
||||||
|
credentials->get_section_keys(option_section, &options);
|
||||||
|
|
||||||
|
for (const String &E : options) {
|
||||||
|
Variant value = credentials->get_value(option_section, E);
|
||||||
|
preset->set(E, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
add_export_preset(preset);
|
add_export_preset(preset);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
@ -818,6 +818,14 @@ String EditorExportPlatform::_export_customize(const String &p_path, LocalVector
|
|||||||
return save_path.is_empty() ? p_path : save_path;
|
return save_path.is_empty() ? p_path : save_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String EditorExportPlatform::_get_script_encryption_key(const Ref<EditorExportPreset> &p_preset) const {
|
||||||
|
const String from_env = OS::get_singleton()->get_environment(ENV_SCRIPT_ENCRYPTION_KEY);
|
||||||
|
if (!from_env.is_empty()) {
|
||||||
|
return from_env.to_lower();
|
||||||
|
}
|
||||||
|
return p_preset->get_script_encryption_key().to_lower();
|
||||||
|
}
|
||||||
|
|
||||||
Vector<String> EditorExportPlatform::get_forced_export_files() {
|
Vector<String> EditorExportPlatform::get_forced_export_files() {
|
||||||
Vector<String> files;
|
Vector<String> files;
|
||||||
|
|
||||||
@ -946,7 +954,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get encryption key.
|
// Get encryption key.
|
||||||
String script_key = p_preset->get_script_encryption_key().to_lower();
|
String script_key = _get_script_encryption_key(p_preset);
|
||||||
key.resize(32);
|
key.resize(32);
|
||||||
if (script_key.length() == 64) {
|
if (script_key.length() == 64) {
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
@ -1577,7 +1585,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b
|
|||||||
Ref<FileAccess> fhead = f;
|
Ref<FileAccess> fhead = f;
|
||||||
|
|
||||||
if (enc_pck && enc_directory) {
|
if (enc_pck && enc_directory) {
|
||||||
String script_key = p_preset->get_script_encryption_key().to_lower();
|
String script_key = _get_script_encryption_key(p_preset);
|
||||||
Vector<uint8_t> key;
|
Vector<uint8_t> key;
|
||||||
key.resize(32);
|
key.resize(32);
|
||||||
if (script_key.length() == 64) {
|
if (script_key.length() == 64) {
|
||||||
|
@ -43,6 +43,8 @@ struct EditorProgress;
|
|||||||
|
|
||||||
class EditorExportPlugin;
|
class EditorExportPlugin;
|
||||||
|
|
||||||
|
const String ENV_SCRIPT_ENCRYPTION_KEY = "GODOT_SCRIPT_ENCRYPTION_KEY";
|
||||||
|
|
||||||
class EditorExportPlatform : public RefCounted {
|
class EditorExportPlatform : public RefCounted {
|
||||||
GDCLASS(EditorExportPlatform, RefCounted);
|
GDCLASS(EditorExportPlatform, RefCounted);
|
||||||
|
|
||||||
@ -116,6 +118,7 @@ private:
|
|||||||
bool _is_editable_ancestor(Node *p_root, Node *p_node);
|
bool _is_editable_ancestor(Node *p_root, Node *p_node);
|
||||||
|
|
||||||
String _export_customize(const String &p_path, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins, LocalVector<Ref<EditorExportPlugin>> &customize_scenes_plugins, HashMap<String, FileExportCache> &export_cache, const String &export_base_path, bool p_force_save);
|
String _export_customize(const String &p_path, LocalVector<Ref<EditorExportPlugin>> &customize_resources_plugins, LocalVector<Ref<EditorExportPlugin>> &customize_scenes_plugins, HashMap<String, FileExportCache> &export_cache, const String &export_base_path, bool p_force_save);
|
||||||
|
String _get_script_encryption_key(const Ref<EditorExportPreset> &p_preset) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct ExportNotifier {
|
struct ExportNotifier {
|
||||||
|
@ -302,4 +302,15 @@ String EditorExportPreset::get_script_encryption_key() const {
|
|||||||
return script_key;
|
return script_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variant EditorExportPreset::get_or_env(const StringName &p_name, const String &p_env_var, bool *r_valid) const {
|
||||||
|
const String from_env = OS::get_singleton()->get_environment(p_env_var);
|
||||||
|
if (!from_env.is_empty()) {
|
||||||
|
if (r_valid) {
|
||||||
|
*r_valid = true;
|
||||||
|
}
|
||||||
|
return from_env;
|
||||||
|
}
|
||||||
|
return get(p_name, r_valid);
|
||||||
|
}
|
||||||
|
|
||||||
EditorExportPreset::EditorExportPreset() {}
|
EditorExportPreset::EditorExportPreset() {}
|
||||||
|
@ -152,6 +152,8 @@ public:
|
|||||||
void set_script_encryption_key(const String &p_key);
|
void set_script_encryption_key(const String &p_key);
|
||||||
String get_script_encryption_key() const;
|
String get_script_encryption_key() const;
|
||||||
|
|
||||||
|
Variant get_or_env(const StringName &p_name, const String &p_env_var, bool *r_valid = nullptr) const;
|
||||||
|
|
||||||
const List<PropertyInfo> &get_properties() const { return properties; }
|
const List<PropertyInfo> &get_properties() const { return properties; }
|
||||||
|
|
||||||
EditorExportPreset();
|
EditorExportPreset();
|
||||||
|
@ -58,21 +58,27 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="keystore/debug" type="String" setter="" getter="">
|
<member name="keystore/debug" type="String" setter="" getter="">
|
||||||
Path of the debug keystore file.
|
Path of the debug keystore file.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_DEBUG_PATH[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="keystore/debug_password" type="String" setter="" getter="">
|
<member name="keystore/debug_password" type="String" setter="" getter="">
|
||||||
Password for the debug keystore file.
|
Password for the debug keystore file.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_DEBUG_PASSWORD[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="keystore/debug_user" type="String" setter="" getter="">
|
<member name="keystore/debug_user" type="String" setter="" getter="">
|
||||||
User name for the debug keystore file.
|
User name for the debug keystore file.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_DEBUG_USER[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="keystore/release" type="String" setter="" getter="">
|
<member name="keystore/release" type="String" setter="" getter="">
|
||||||
Path of the release keystore file.
|
Path of the release keystore file.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_RELEASE_PATH[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="keystore/release_password" type="String" setter="" getter="">
|
<member name="keystore/release_password" type="String" setter="" getter="">
|
||||||
Password for the release keystore file.
|
Password for the release keystore file.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="keystore/release_user" type="String" setter="" getter="">
|
<member name="keystore/release_user" type="String" setter="" getter="">
|
||||||
User name for the release keystore file.
|
User name for the release keystore file.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_ANDROID_KEYSTORE_RELEASE_USER[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="launcher_icons/adaptive_background_432x432" type="String" setter="" getter="">
|
<member name="launcher_icons/adaptive_background_432x432" type="String" setter="" getter="">
|
||||||
Background layer of the application adaptive icon file.
|
Background layer of the application adaptive icon file.
|
||||||
|
@ -1825,12 +1825,12 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
|
|||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("architectures"), abi)), is_default));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("architectures"), abi)), is_default));
|
||||||
}
|
}
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
|
||||||
@ -2277,9 +2277,9 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<Edito
|
|||||||
|
|
||||||
// Validate the rest of the export configuration.
|
// Validate the rest of the export configuration.
|
||||||
|
|
||||||
String dk = p_preset->get("keystore/debug");
|
String dk = p_preset->get_or_env("keystore/debug", ENV_ANDROID_KEYSTORE_DEBUG_PATH);
|
||||||
String dk_user = p_preset->get("keystore/debug_user");
|
String dk_user = p_preset->get_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER);
|
||||||
String dk_password = p_preset->get("keystore/debug_password");
|
String dk_password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS);
|
||||||
|
|
||||||
if ((dk.is_empty() || dk_user.is_empty() || dk_password.is_empty()) && (!dk.is_empty() || !dk_user.is_empty() || !dk_password.is_empty())) {
|
if ((dk.is_empty() || dk_user.is_empty() || dk_password.is_empty()) && (!dk.is_empty() || !dk_user.is_empty() || !dk_password.is_empty())) {
|
||||||
valid = false;
|
valid = false;
|
||||||
@ -2294,9 +2294,9 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<Edito
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String rk = p_preset->get("keystore/release");
|
String rk = p_preset->get_or_env("keystore/release", ENV_ANDROID_KEYSTORE_RELEASE_PATH);
|
||||||
String rk_user = p_preset->get("keystore/release_user");
|
String rk_user = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER);
|
||||||
String rk_password = p_preset->get("keystore/release_password");
|
String rk_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS);
|
||||||
|
|
||||||
if ((rk.is_empty() || rk_user.is_empty() || rk_password.is_empty()) && (!rk.is_empty() || !rk_user.is_empty() || !rk_password.is_empty())) {
|
if ((rk.is_empty() || rk_user.is_empty() || rk_password.is_empty()) && (!rk.is_empty() || !rk_user.is_empty() || !rk_password.is_empty())) {
|
||||||
valid = false;
|
valid = false;
|
||||||
@ -2507,9 +2507,9 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
|
|||||||
Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep) {
|
Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep) {
|
||||||
int export_format = int(p_preset->get("gradle_build/export_format"));
|
int export_format = int(p_preset->get("gradle_build/export_format"));
|
||||||
String export_label = export_format == EXPORT_FORMAT_AAB ? "AAB" : "APK";
|
String export_label = export_format == EXPORT_FORMAT_AAB ? "AAB" : "APK";
|
||||||
String release_keystore = p_preset->get("keystore/release");
|
String release_keystore = p_preset->get_or_env("keystore/release", ENV_ANDROID_KEYSTORE_RELEASE_PATH);
|
||||||
String release_username = p_preset->get("keystore/release_user");
|
String release_username = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER);
|
||||||
String release_password = p_preset->get("keystore/release_password");
|
String release_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS);
|
||||||
String target_sdk_version = p_preset->get("gradle_build/target_sdk");
|
String target_sdk_version = p_preset->get("gradle_build/target_sdk");
|
||||||
if (!target_sdk_version.is_valid_int()) {
|
if (!target_sdk_version.is_valid_int()) {
|
||||||
target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
|
target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
|
||||||
@ -2529,9 +2529,9 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
|
|||||||
String password;
|
String password;
|
||||||
String user;
|
String user;
|
||||||
if (p_debug) {
|
if (p_debug) {
|
||||||
keystore = p_preset->get("keystore/debug");
|
keystore = p_preset->get_or_env("keystore/debug", ENV_ANDROID_KEYSTORE_DEBUG_PATH);
|
||||||
password = p_preset->get("keystore/debug_password");
|
password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS);
|
||||||
user = p_preset->get("keystore/debug_user");
|
user = p_preset->get_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER);
|
||||||
|
|
||||||
if (keystore.is_empty()) {
|
if (keystore.is_empty()) {
|
||||||
keystore = EDITOR_GET("export/android/debug_keystore");
|
keystore = EDITOR_GET("export/android/debug_keystore");
|
||||||
@ -2886,9 +2886,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
|
|||||||
|
|
||||||
if (should_sign) {
|
if (should_sign) {
|
||||||
if (p_debug) {
|
if (p_debug) {
|
||||||
String debug_keystore = p_preset->get("keystore/debug");
|
String debug_keystore = p_preset->get_or_env("keystore/debug", ENV_ANDROID_KEYSTORE_DEBUG_PATH);
|
||||||
String debug_password = p_preset->get("keystore/debug_password");
|
String debug_password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS);
|
||||||
String debug_user = p_preset->get("keystore/debug_user");
|
String debug_user = p_preset->get_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER);
|
||||||
|
|
||||||
if (debug_keystore.is_empty()) {
|
if (debug_keystore.is_empty()) {
|
||||||
debug_keystore = EDITOR_GET("export/android/debug_keystore");
|
debug_keystore = EDITOR_GET("export/android/debug_keystore");
|
||||||
@ -2908,9 +2908,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
|
|||||||
cmdline.push_back("-Pdebug_keystore_password=" + debug_password); // argument to specify the debug keystore password.
|
cmdline.push_back("-Pdebug_keystore_password=" + debug_password); // argument to specify the debug keystore password.
|
||||||
} else {
|
} else {
|
||||||
// Pass the release keystore info as well
|
// Pass the release keystore info as well
|
||||||
String release_keystore = p_preset->get("keystore/release");
|
String release_keystore = p_preset->get_or_env("keystore/release", ENV_ANDROID_KEYSTORE_RELEASE_PATH);
|
||||||
String release_username = p_preset->get("keystore/release_user");
|
String release_username = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER);
|
||||||
String release_password = p_preset->get("keystore/release_password");
|
String release_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS);
|
||||||
if (release_keystore.is_relative_path()) {
|
if (release_keystore.is_relative_path()) {
|
||||||
release_keystore = OS::get_singleton()->get_resource_dir().path_join(release_keystore).simplify_path();
|
release_keystore = OS::get_singleton()->get_resource_dir().path_join(release_keystore).simplify_path();
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,15 @@ const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="
|
|||||||
</layer-list>
|
</layer-list>
|
||||||
)SPLASH";
|
)SPLASH";
|
||||||
|
|
||||||
|
// Optional environment variables for defining confidential information. If any
|
||||||
|
// of these is set, they will override the values set in the credentials file.
|
||||||
|
const String ENV_ANDROID_KEYSTORE_DEBUG_PATH = "GODOT_ANDROID_KEYSTORE_DEBUG_PATH";
|
||||||
|
const String ENV_ANDROID_KEYSTORE_DEBUG_USER = "GODOT_ANDROID_KEYSTORE_DEBUG_USER";
|
||||||
|
const String ENV_ANDROID_KEYSTORE_DEBUG_PASS = "GODOT_ANDROID_KEYSTORE_DEBUG_PASSWORD";
|
||||||
|
const String ENV_ANDROID_KEYSTORE_RELEASE_PATH = "GODOT_ANDROID_KEYSTORE_RELEASE_PATH";
|
||||||
|
const String ENV_ANDROID_KEYSTORE_RELEASE_USER = "GODOT_ANDROID_KEYSTORE_RELEASE_USER";
|
||||||
|
const String ENV_ANDROID_KEYSTORE_RELEASE_PASS = "GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD";
|
||||||
|
|
||||||
struct LauncherIcon {
|
struct LauncherIcon {
|
||||||
const char *export_path;
|
const char *export_path;
|
||||||
int dimensions = 0;
|
int dimensions = 0;
|
||||||
|
@ -35,9 +35,11 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="application/provisioning_profile_uuid_debug" type="String" setter="" getter="">
|
<member name="application/provisioning_profile_uuid_debug" type="String" setter="" getter="">
|
||||||
UUID of the provisioning profile. If left empty, Xcode will download or create a provisioning profile automatically. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url].
|
UUID of the provisioning profile. If left empty, Xcode will download or create a provisioning profile automatically. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url].
|
||||||
|
Can be overridden with the environment variable [code]GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="application/provisioning_profile_uuid_release" type="String" setter="" getter="">
|
<member name="application/provisioning_profile_uuid_release" type="String" setter="" getter="">
|
||||||
UUID of the provisioning profile. If left empty, Xcode will download or create a provisioning profile automatically. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url].
|
UUID of the provisioning profile. If left empty, Xcode will download or create a provisioning profile automatically. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url].
|
||||||
|
Can be overridden with the environment variable [code]GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="application/short_version" type="String" setter="" getter="">
|
<member name="application/short_version" type="String" setter="" getter="">
|
||||||
Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
|
Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
|
||||||
|
@ -160,10 +160,10 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
|
|||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), "", false, true));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_debug"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_debug", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_debug", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Developer"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_debug", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Developer"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_debug", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 1));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_debug", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 1));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_release"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_release", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_release", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Distribution"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_release", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Distribution"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_release", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 0));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_release", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 0));
|
||||||
|
|
||||||
@ -253,8 +253,8 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
|
|||||||
};
|
};
|
||||||
String dbg_sign_id = p_preset->get("application/code_sign_identity_debug").operator String().is_empty() ? "iPhone Developer" : p_preset->get("application/code_sign_identity_debug");
|
String dbg_sign_id = p_preset->get("application/code_sign_identity_debug").operator String().is_empty() ? "iPhone Developer" : p_preset->get("application/code_sign_identity_debug");
|
||||||
String rel_sign_id = p_preset->get("application/code_sign_identity_release").operator String().is_empty() ? "iPhone Distribution" : p_preset->get("application/code_sign_identity_release");
|
String rel_sign_id = p_preset->get("application/code_sign_identity_release").operator String().is_empty() ? "iPhone Distribution" : p_preset->get("application/code_sign_identity_release");
|
||||||
bool dbg_manual = !p_preset->get("application/provisioning_profile_uuid_debug").operator String().is_empty() || (dbg_sign_id != "iPhone Developer");
|
bool dbg_manual = !p_preset->get_or_env("application/provisioning_profile_uuid_debug", ENV_IOS_PROFILE_UUID_DEBUG).operator String().is_empty() || (dbg_sign_id != "iPhone Developer");
|
||||||
bool rel_manual = !p_preset->get("application/provisioning_profile_uuid_release").operator String().is_empty() || (rel_sign_id != "iPhone Distribution");
|
bool rel_manual = !p_preset->get_or_env("application/provisioning_profile_uuid_release", ENV_IOS_PROFILE_UUID_RELEASE).operator String().is_empty() || (rel_sign_id != "iPhone Distribution");
|
||||||
String str;
|
String str;
|
||||||
String strnew;
|
String strnew;
|
||||||
str.parse_utf8((const char *)pfile.ptr(), pfile.size());
|
str.parse_utf8((const char *)pfile.ptr(), pfile.size());
|
||||||
@ -288,9 +288,9 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
|
|||||||
int export_method = p_preset->get(p_debug ? "application/export_method_debug" : "application/export_method_release");
|
int export_method = p_preset->get(p_debug ? "application/export_method_debug" : "application/export_method_release");
|
||||||
strnew += lines[i].replace("$export_method", export_method_string[export_method]) + "\n";
|
strnew += lines[i].replace("$export_method", export_method_string[export_method]) + "\n";
|
||||||
} else if (lines[i].find("$provisioning_profile_uuid_release") != -1) {
|
} else if (lines[i].find("$provisioning_profile_uuid_release") != -1) {
|
||||||
strnew += lines[i].replace("$provisioning_profile_uuid_release", p_preset->get("application/provisioning_profile_uuid_release")) + "\n";
|
strnew += lines[i].replace("$provisioning_profile_uuid_release", p_preset->get_or_env("application/provisioning_profile_uuid_release", ENV_IOS_PROFILE_UUID_RELEASE)) + "\n";
|
||||||
} else if (lines[i].find("$provisioning_profile_uuid_debug") != -1) {
|
} else if (lines[i].find("$provisioning_profile_uuid_debug") != -1) {
|
||||||
strnew += lines[i].replace("$provisioning_profile_uuid_debug", p_preset->get("application/provisioning_profile_uuid_debug")) + "\n";
|
strnew += lines[i].replace("$provisioning_profile_uuid_debug", p_preset->get_or_env("application/provisioning_profile_uuid_debug", ENV_IOS_PROFILE_UUID_DEBUG)) + "\n";
|
||||||
} else if (lines[i].find("$code_sign_style_debug") != -1) {
|
} else if (lines[i].find("$code_sign_style_debug") != -1) {
|
||||||
if (dbg_manual) {
|
if (dbg_manual) {
|
||||||
strnew += lines[i].replace("$code_sign_style_debug", "Manual") + "\n";
|
strnew += lines[i].replace("$code_sign_style_debug", "Manual") + "\n";
|
||||||
@ -304,7 +304,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
|
|||||||
strnew += lines[i].replace("$code_sign_style_release", "Automatic") + "\n";
|
strnew += lines[i].replace("$code_sign_style_release", "Automatic") + "\n";
|
||||||
}
|
}
|
||||||
} else if (lines[i].find("$provisioning_profile_uuid") != -1) {
|
} else if (lines[i].find("$provisioning_profile_uuid") != -1) {
|
||||||
String uuid = p_debug ? p_preset->get("application/provisioning_profile_uuid_debug") : p_preset->get("application/provisioning_profile_uuid_release");
|
String uuid = p_debug ? p_preset->get_or_env("application/provisioning_profile_uuid_debug", ENV_IOS_PROFILE_UUID_DEBUG) : p_preset->get_or_env("application/provisioning_profile_uuid_release", ENV_IOS_PROFILE_UUID_RELEASE);
|
||||||
strnew += lines[i].replace("$provisioning_profile_uuid", uuid) + "\n";
|
strnew += lines[i].replace("$provisioning_profile_uuid", uuid) + "\n";
|
||||||
} else if (lines[i].find("$code_sign_identity_debug") != -1) {
|
} else if (lines[i].find("$code_sign_identity_debug") != -1) {
|
||||||
strnew += lines[i].replace("$code_sign_identity_debug", dbg_sign_id) + "\n";
|
strnew += lines[i].replace("$code_sign_identity_debug", dbg_sign_id) + "\n";
|
||||||
|
@ -49,6 +49,11 @@
|
|||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
// Optional environment variables for defining confidential information. If any
|
||||||
|
// of these is set, they will override the values set in the credentials file.
|
||||||
|
const String ENV_IOS_PROFILE_UUID_DEBUG = "GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG";
|
||||||
|
const String ENV_IOS_PROFILE_UUID_RELEASE = "GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE";
|
||||||
|
|
||||||
class EditorExportPlatformIOS : public EditorExportPlatform {
|
class EditorExportPlatformIOS : public EditorExportPlatform {
|
||||||
GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
|
GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
|
||||||
|
|
||||||
|
@ -50,9 +50,11 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="codesign/certificate_file" type="String" setter="" getter="">
|
<member name="codesign/certificate_file" type="String" setter="" getter="">
|
||||||
PKCS #12 certificate file used to sign [code].app[/code] bundle.
|
PKCS #12 certificate file used to sign [code].app[/code] bundle.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_CODESIGN_CERTIFICATE_FILE[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="codesign/certificate_password" type="String" setter="" getter="">
|
<member name="codesign/certificate_password" type="String" setter="" getter="">
|
||||||
Password for the certificate file used to sign [code].app[/code] bundle.
|
Password for the certificate file used to sign [code].app[/code] bundle.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_CODESIGN_CERTIFICATE_PASSWORD[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="codesign/codesign" type="int" setter="" getter="">
|
<member name="codesign/codesign" type="int" setter="" getter="">
|
||||||
Tool to use for code signing.
|
Tool to use for code signing.
|
||||||
@ -138,6 +140,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="codesign/provisioning_profile" type="String" setter="" getter="">
|
<member name="codesign/provisioning_profile" type="String" setter="" getter="">
|
||||||
Provisioning profile file downloaded from Apple developer account dashboard. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url].
|
Provisioning profile file downloaded from Apple developer account dashboard. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url].
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_CODESIGN_PROVISIONING_PROFILE[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="custom_template/debug" type="String" setter="" getter="">
|
<member name="custom_template/debug" type="String" setter="" getter="">
|
||||||
Path to the custom export template. If left empty, default template is used.
|
Path to the custom export template. If left empty, default template is used.
|
||||||
@ -156,18 +159,23 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="notarization/api_key" type="String" setter="" getter="">
|
<member name="notarization/api_key" type="String" setter="" getter="">
|
||||||
Apple App Store Connect API issuer key file.
|
Apple App Store Connect API issuer key file.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_API_KEY[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="notarization/api_key_id" type="String" setter="" getter="">
|
<member name="notarization/api_key_id" type="String" setter="" getter="">
|
||||||
Apple App Store Connect API issuer key ID.
|
Apple App Store Connect API issuer key ID.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_API_KEY_ID[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="notarization/api_uuid" type="String" setter="" getter="">
|
<member name="notarization/api_uuid" type="String" setter="" getter="">
|
||||||
Apple App Store Connect API issuer UUID.
|
Apple App Store Connect API issuer UUID.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_API_UUID[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="notarization/apple_id_name" type="String" setter="" getter="">
|
<member name="notarization/apple_id_name" type="String" setter="" getter="">
|
||||||
Apple ID account name (email address).
|
Apple ID account name (email address).
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_APPLE_ID_NAME[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="notarization/apple_id_password" type="String" setter="" getter="">
|
<member name="notarization/apple_id_password" type="String" setter="" getter="">
|
||||||
Apple ID app-specific password.
|
Apple ID app-specific password.
|
||||||
|
Can be overridden with the environment variable [code]GODOT_MACOS_NOTARIZATION_APPLE_ID_PASSWORD[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="notarization/notarization" type="int" setter="" getter="">
|
<member name="notarization/notarization" type="int" setter="" getter="">
|
||||||
Tool to use for notarization.
|
Tool to use for notarization.
|
||||||
|
@ -73,7 +73,7 @@ String EditorExportPlatformMacOS::get_export_option_warning(const EditorExportPr
|
|||||||
ad_hoc = true;
|
ad_hoc = true;
|
||||||
} break;
|
} break;
|
||||||
case 2: { // "rcodesign"
|
case 2: { // "rcodesign"
|
||||||
ad_hoc = p_preset->get("codesign/certificate_file").operator String().is_empty() || p_preset->get("codesign/certificate_password").operator String().is_empty();
|
ad_hoc = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty() || p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty();
|
||||||
} break;
|
} break;
|
||||||
#ifdef MACOS_ENABLED
|
#ifdef MACOS_ENABLED
|
||||||
case 3: { // "codesign"
|
case 3: { // "codesign"
|
||||||
@ -114,7 +114,7 @@ String EditorExportPlatformMacOS::get_export_option_warning(const EditorExportPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p_name == "codesign/provisioning_profile" && dist_type == 2) {
|
if (p_name == "codesign/provisioning_profile" && dist_type == 2) {
|
||||||
String pprof = p_preset->get("codesign/provisioning_profile");
|
String pprof = p_preset->get_or_env("codesign/provisioning_profile", ENV_MAC_CODESIGN_PROFILE);
|
||||||
if (pprof.is_empty()) {
|
if (pprof.is_empty()) {
|
||||||
return TTR("Provisioning profile is required for App Store distribution.");
|
return TTR("Provisioning profile is required for App Store distribution.");
|
||||||
}
|
}
|
||||||
@ -154,8 +154,8 @@ String EditorExportPlatformMacOS::get_export_option_warning(const EditorExportPr
|
|||||||
|
|
||||||
if (notary_tool == 2 || notary_tool == 3) {
|
if (notary_tool == 2 || notary_tool == 3) {
|
||||||
if (p_name == "notarization/apple_id_name" || p_name == "notarization/api_uuid") {
|
if (p_name == "notarization/apple_id_name" || p_name == "notarization/api_uuid") {
|
||||||
String apple_id = p_preset->get("notarization/apple_id_name");
|
String apple_id = p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID);
|
||||||
String api_uuid = p_preset->get("notarization/api_uuid");
|
String api_uuid = p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID);
|
||||||
if (apple_id.is_empty() && api_uuid.is_empty()) {
|
if (apple_id.is_empty() && api_uuid.is_empty()) {
|
||||||
return TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified.");
|
return TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified.");
|
||||||
}
|
}
|
||||||
@ -164,28 +164,28 @@ String EditorExportPlatformMacOS::get_export_option_warning(const EditorExportPr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p_name == "notarization/apple_id_password") {
|
if (p_name == "notarization/apple_id_password") {
|
||||||
String apple_id = p_preset->get("notarization/apple_id_name");
|
String apple_id = p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID);
|
||||||
String apple_pass = p_preset->get("notarization/apple_id_password");
|
String apple_pass = p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS);
|
||||||
if (!apple_id.is_empty() && apple_pass.is_empty()) {
|
if (!apple_id.is_empty() && apple_pass.is_empty()) {
|
||||||
return TTR("Apple ID password not specified.");
|
return TTR("Apple ID password not specified.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p_name == "notarization/api_key_id") {
|
if (p_name == "notarization/api_key_id") {
|
||||||
String api_uuid = p_preset->get("notarization/api_uuid");
|
String api_uuid = p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID);
|
||||||
String api_key = p_preset->get("notarization/api_key_id");
|
String api_key = p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID);
|
||||||
if (!api_uuid.is_empty() && api_key.is_empty()) {
|
if (!api_uuid.is_empty() && api_key.is_empty()) {
|
||||||
return TTR("App Store Connect API key ID not specified.");
|
return TTR("App Store Connect API key ID not specified.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (notary_tool == 1) {
|
} else if (notary_tool == 1) {
|
||||||
if (p_name == "notarization/api_uuid") {
|
if (p_name == "notarization/api_uuid") {
|
||||||
String api_uuid = p_preset->get("notarization/api_uuid");
|
String api_uuid = p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID);
|
||||||
if (api_uuid.is_empty()) {
|
if (api_uuid.is_empty()) {
|
||||||
return TTR("App Store Connect issuer ID name not specified.");
|
return TTR("App Store Connect issuer ID name not specified.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p_name == "notarization/api_key_id") {
|
if (p_name == "notarization/api_key_id") {
|
||||||
String api_key = p_preset->get("notarization/api_key_id");
|
String api_key = p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID);
|
||||||
if (api_key.is_empty()) {
|
if (api_key.is_empty()) {
|
||||||
return TTR("App Store Connect API key ID not specified.");
|
return TTR("App Store Connect API key ID not specified.");
|
||||||
}
|
}
|
||||||
@ -398,10 +398,10 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
|
|||||||
// "codesign" only options:
|
// "codesign" only options:
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_PLACEHOLDER_TEXT, "Type: Name (ID)"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_PLACEHOLDER_TEXT, "Type: Name (ID)"), ""));
|
||||||
// "rcodesign" only options:
|
// "rcodesign" only options:
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_file", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_file", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_password", PROPERTY_HINT_PASSWORD), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/certificate_password", PROPERTY_HINT_PASSWORD, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
// "codesign" and "rcodesign" only options:
|
// "codesign" and "rcodesign" only options:
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/provisioning_profile", PROPERTY_HINT_GLOBAL_FILE, "*.provisionprofile"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/provisioning_profile", PROPERTY_HINT_GLOBAL_FILE, "*.provisionprofile", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements/custom_file", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), "", true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements/custom_file", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), "", true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_jit_code_execution"), false));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_jit_code_execution"), false));
|
||||||
@ -434,12 +434,12 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
|
|||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,rcodesign"), 0, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,rcodesign"), 0, true));
|
||||||
#endif
|
#endif
|
||||||
// "altool" and "notarytool" only options:
|
// "altool" and "notarytool" only options:
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Apple ID email"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Apple ID email", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_password", PROPERTY_HINT_PASSWORD, "Enable two-factor authentication and provide app-specific password"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_password", PROPERTY_HINT_PASSWORD, "Enable two-factor authentication and provide app-specific password", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true));
|
||||||
// "altool", "notarytool" and "rcodesign" only options:
|
// "altool", "notarytool" and "rcodesign" only options:
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_uuid", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect issuer ID UUID"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_uuid", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect issuer ID UUID", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key", PROPERTY_HINT_GLOBAL_FILE, "*.p8"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key", PROPERTY_HINT_GLOBAL_FILE, "*.p8", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key_id", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect API key ID"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key_id", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect API key ID", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "", false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "", false, true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/microphone_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary()));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/microphone_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary()));
|
||||||
@ -776,24 +776,24 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres
|
|||||||
|
|
||||||
args.push_back("notary-submit");
|
args.push_back("notary-submit");
|
||||||
|
|
||||||
if (p_preset->get("notarization/api_uuid") == "") {
|
if (p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect issuer ID name not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect issuer ID name not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
if (p_preset->get("notarization/api_key") == "") {
|
if (p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back("--api-issuer");
|
args.push_back("--api-issuer");
|
||||||
args.push_back(p_preset->get("notarization/api_uuid"));
|
args.push_back(p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID));
|
||||||
|
|
||||||
args.push_back("--api-key");
|
args.push_back("--api-key");
|
||||||
args.push_back(p_preset->get("notarization/api_key_id"));
|
args.push_back(p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID));
|
||||||
|
|
||||||
if (!p_preset->get("notarization/api_key").operator String().is_empty()) {
|
if (!p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY).operator String().is_empty()) {
|
||||||
args.push_back("--api-key-path");
|
args.push_back("--api-key-path");
|
||||||
args.push_back(p_preset->get("notarization/api_key"));
|
args.push_back(p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back(p_path);
|
args.push_back(p_path);
|
||||||
@ -840,40 +840,40 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres
|
|||||||
|
|
||||||
args.push_back(p_path);
|
args.push_back(p_path);
|
||||||
|
|
||||||
if (p_preset->get("notarization/apple_id_name") == "" && p_preset->get("notarization/api_uuid") == "") {
|
if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) == "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
if (p_preset->get("notarization/apple_id_name") != "" && p_preset->get("notarization/api_uuid") != "") {
|
if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) != "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_preset->get("notarization/apple_id_name") != "") {
|
if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "") {
|
||||||
if (p_preset->get("notarization/apple_id_password") == "") {
|
if (p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Apple ID password not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Apple ID password not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
args.push_back("--apple-id");
|
args.push_back("--apple-id");
|
||||||
args.push_back(p_preset->get("notarization/apple_id_name"));
|
args.push_back(p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID));
|
||||||
|
|
||||||
args.push_back("--password");
|
args.push_back("--password");
|
||||||
args.push_back(p_preset->get("notarization/apple_id_password"));
|
args.push_back(p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS));
|
||||||
} else {
|
} else {
|
||||||
if (p_preset->get("notarization/api_key_id") == "") {
|
if (p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
args.push_back("--issuer");
|
args.push_back("--issuer");
|
||||||
args.push_back(p_preset->get("notarization/api_uuid"));
|
args.push_back(p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID));
|
||||||
|
|
||||||
if (!p_preset->get("notarization/api_key").operator String().is_empty()) {
|
if (!p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY).operator String().is_empty()) {
|
||||||
args.push_back("--key");
|
args.push_back("--key");
|
||||||
args.push_back(p_preset->get("notarization/api_key"));
|
args.push_back(p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back("--key-id");
|
args.push_back("--key-id");
|
||||||
args.push_back(p_preset->get("notarization/api_key_id"));
|
args.push_back(p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back("--no-progress");
|
args.push_back("--no-progress");
|
||||||
@ -925,35 +925,35 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres
|
|||||||
args.push_back("--primary-bundle-id");
|
args.push_back("--primary-bundle-id");
|
||||||
args.push_back(p_preset->get("application/bundle_identifier"));
|
args.push_back(p_preset->get("application/bundle_identifier"));
|
||||||
|
|
||||||
if (p_preset->get("notarization/apple_id_name") == "" && p_preset->get("notarization/api_uuid") == "") {
|
if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) == "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
if (p_preset->get("notarization/apple_id_name") != "" && p_preset->get("notarization/api_uuid") != "") {
|
if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) != "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_preset->get("notarization/apple_id_name") != "") {
|
if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "") {
|
||||||
if (p_preset->get("notarization/apple_id_password") == "") {
|
if (p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Apple ID password not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Apple ID password not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
args.push_back("--username");
|
args.push_back("--username");
|
||||||
args.push_back(p_preset->get("notarization/apple_id_name"));
|
args.push_back(p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID));
|
||||||
|
|
||||||
args.push_back("--password");
|
args.push_back("--password");
|
||||||
args.push_back(p_preset->get("notarization/apple_id_password"));
|
args.push_back(p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS));
|
||||||
} else {
|
} else {
|
||||||
if (p_preset->get("notarization/api_key") == "") {
|
if (p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY) == "") {
|
||||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified."));
|
add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified."));
|
||||||
return Error::FAILED;
|
return Error::FAILED;
|
||||||
}
|
}
|
||||||
args.push_back("--apiIssuer");
|
args.push_back("--apiIssuer");
|
||||||
args.push_back(p_preset->get("notarization/api_uuid"));
|
args.push_back(p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID));
|
||||||
|
|
||||||
args.push_back("--apiKey");
|
args.push_back("--apiKey");
|
||||||
args.push_back(p_preset->get("notarization/api_key_id"));
|
args.push_back(p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push_back("--type");
|
args.push_back("--type");
|
||||||
@ -1032,8 +1032,8 @@ Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_pre
|
|||||||
args.push_back(p_ent_path);
|
args.push_back(p_ent_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
String certificate_file = p_preset->get("codesign/certificate_file");
|
String certificate_file = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE);
|
||||||
String certificate_pass = p_preset->get("codesign/certificate_password");
|
String certificate_pass = p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_PASS);
|
||||||
if (!certificate_file.is_empty() && !certificate_pass.is_empty()) {
|
if (!certificate_file.is_empty() && !certificate_pass.is_empty()) {
|
||||||
args.push_back("--p12-file");
|
args.push_back("--p12-file");
|
||||||
args.push_back(certificate_file);
|
args.push_back(certificate_file);
|
||||||
@ -1763,7 +1763,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
|
|||||||
ad_hoc = true;
|
ad_hoc = true;
|
||||||
} break;
|
} break;
|
||||||
case 2: { // "rcodesign"
|
case 2: { // "rcodesign"
|
||||||
ad_hoc = p_preset->get("codesign/certificate_file").operator String().is_empty() || p_preset->get("codesign/certificate_password").operator String().is_empty();
|
ad_hoc = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty() || p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_PASS).operator String().is_empty();
|
||||||
} break;
|
} break;
|
||||||
#ifdef MACOS_ENABLED
|
#ifdef MACOS_ENABLED
|
||||||
case 3: { // "codesign"
|
case 3: { // "codesign"
|
||||||
@ -1857,7 +1857,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
|
|||||||
|
|
||||||
int dist_type = p_preset->get("export/distribution_type");
|
int dist_type = p_preset->get("export/distribution_type");
|
||||||
if (dist_type == 2) {
|
if (dist_type == 2) {
|
||||||
String pprof = p_preset->get("codesign/provisioning_profile");
|
String pprof = p_preset->get_or_env("codesign/provisioning_profile", ENV_MAC_CODESIGN_PROFILE);
|
||||||
String teamid = p_preset->get("codesign/apple_team_id");
|
String teamid = p_preset->get("codesign/apple_team_id");
|
||||||
String bid = p_preset->get("application/bundle_identifier");
|
String bid = p_preset->get("application/bundle_identifier");
|
||||||
if (!pprof.is_empty() && !teamid.is_empty()) {
|
if (!pprof.is_empty() && !teamid.is_empty()) {
|
||||||
@ -1990,7 +1990,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
|
|||||||
if (err == OK && sign_enabled) {
|
if (err == OK && sign_enabled) {
|
||||||
int dist_type = p_preset->get("export/distribution_type");
|
int dist_type = p_preset->get("export/distribution_type");
|
||||||
if (dist_type == 2) {
|
if (dist_type == 2) {
|
||||||
String pprof = p_preset->get("codesign/provisioning_profile").operator String();
|
String pprof = p_preset->get_or_env("codesign/provisioning_profile", ENV_MAC_CODESIGN_PROFILE).operator String();
|
||||||
if (!pprof.is_empty()) {
|
if (!pprof.is_empty()) {
|
||||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
err = da->copy(pprof, tmp_app_path_name + "/Contents/embedded.provisionprofile");
|
err = da->copy(pprof, tmp_app_path_name + "/Contents/embedded.provisionprofile");
|
||||||
@ -2147,7 +2147,7 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor
|
|||||||
ad_hoc = true;
|
ad_hoc = true;
|
||||||
} break;
|
} break;
|
||||||
case 2: { // "rcodesign"
|
case 2: { // "rcodesign"
|
||||||
ad_hoc = p_preset->get("codesign/certificate_file").operator String().is_empty() || p_preset->get("codesign/certificate_password").operator String().is_empty();
|
ad_hoc = p_preset->get_or_env("codesign/certificate_file", ENV_MAC_CODESIGN_CERT_FILE).operator String().is_empty() || p_preset->get_or_env("codesign/certificate_password", ENV_MAC_CODESIGN_CERT_PASS).operator String().is_empty();
|
||||||
} break;
|
} break;
|
||||||
#ifdef MACOS_ENABLED
|
#ifdef MACOS_ENABLED
|
||||||
case 3: { // "codesign"
|
case 3: { // "codesign"
|
||||||
|
@ -43,6 +43,17 @@
|
|||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
// Optional environment variables for defining confidential information. If any
|
||||||
|
// of these is set, they will override the values set in the credentials file.
|
||||||
|
const String ENV_MAC_CODESIGN_CERT_FILE = "GODOT_MACOS_CODESIGN_CERTIFICATE_FILE";
|
||||||
|
const String ENV_MAC_CODESIGN_CERT_PASS = "GODOT_MACOS_CODESIGN_CERTIFICATE_PASSWORD";
|
||||||
|
const String ENV_MAC_CODESIGN_PROFILE = "GODOT_MACOS_CODESIGN_PROVISIONING_PROFILE";
|
||||||
|
const String ENV_MAC_NOTARIZATION_UUID = "GODOT_MACOS_NOTARIZATION_API_UUID";
|
||||||
|
const String ENV_MAC_NOTARIZATION_KEY = "GODOT_MACOS_NOTARIZATION_API_KEY";
|
||||||
|
const String ENV_MAC_NOTARIZATION_KEY_ID = "GODOT_MACOS_NOTARIZATION_API_KEY_ID";
|
||||||
|
const String ENV_MAC_NOTARIZATION_APPLE_ID = "GODOT_MACOS_NOTARIZATION_APPLE_ID_NAME";
|
||||||
|
const String ENV_MAC_NOTARIZATION_APPLE_PASS = "GODOT_MACOS_NOTARIZATION_APPLE_ID_PASSWORD";
|
||||||
|
|
||||||
class EditorExportPlatformMacOS : public EditorExportPlatform {
|
class EditorExportPlatformMacOS : public EditorExportPlatform {
|
||||||
GDCLASS(EditorExportPlatformMacOS, EditorExportPlatform);
|
GDCLASS(EditorExportPlatformMacOS, EditorExportPlatform);
|
||||||
|
|
||||||
|
@ -80,8 +80,8 @@ void EditorExportPlatformUWP::get_export_options(List<ExportOption> *r_options)
|
|||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/product_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/product_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/publisher_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/publisher_guid", PROPERTY_HINT_PLACEHOLDER_TEXT, "00000000-0000-0000-0000-000000000000"), ""));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/password"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "signing/password", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "signing/algorithm", PROPERTY_HINT_ENUM, "MD5,SHA1,SHA256"), 2));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "signing/algorithm", PROPERTY_HINT_ENUM, "MD5,SHA1,SHA256"), 2));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/major"), 1));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/major"), 1));
|
||||||
@ -465,8 +465,8 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
|
|||||||
int cert_alg = EDITOR_GET("export/uwp/debug_algorithm");
|
int cert_alg = EDITOR_GET("export/uwp/debug_algorithm");
|
||||||
|
|
||||||
if (!p_debug) {
|
if (!p_debug) {
|
||||||
cert_path = p_preset->get("signing/certificate");
|
cert_path = p_preset->get_or_env("signing/certificate", ENV_UWP_SIGNING_CERT);
|
||||||
cert_pass = p_preset->get("signing/password");
|
cert_pass = p_preset->get_or_env("signing/password", ENV_UWP_SIGNING_PASS);
|
||||||
cert_alg = p_preset->get("signing/algorithm");
|
cert_alg = p_preset->get("signing/algorithm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +85,11 @@ static const char *uwp_device_capabilities[] = {
|
|||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Optional environment variables for defining confidential information. If any
|
||||||
|
// of these is set, they will override the values set in the credentials file.
|
||||||
|
const String ENV_UWP_SIGNING_CERT = "GODOT_UWP_SIGNING_CERTIFICATE";
|
||||||
|
const String ENV_UWP_SIGNING_PASS = "GODOT_UWP_SIGNING_PASSWORD";
|
||||||
|
|
||||||
class EditorExportPlatformUWP : public EditorExportPlatform {
|
class EditorExportPlatformUWP : public EditorExportPlatform {
|
||||||
GDCLASS(EditorExportPlatformUWP, EditorExportPlatform);
|
GDCLASS(EditorExportPlatformUWP, EditorExportPlatform);
|
||||||
|
|
||||||
|
@ -64,12 +64,15 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="codesign/identity" type="String" setter="" getter="">
|
<member name="codesign/identity" type="String" setter="" getter="">
|
||||||
PKCS #12 certificate file used to sign executable or certificate SHA-1 hash (if [member codesign/identity_type] is set to "Use certificate store"). See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
PKCS #12 certificate file used to sign executable or certificate SHA-1 hash (if [member codesign/identity_type] is set to "Use certificate store"). See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
||||||
|
Can be overridden with the environment variable [code]GODOT_WINDOWS_CODESIGN_IDENTITY[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="codesign/identity_type" type="int" setter="" getter="">
|
<member name="codesign/identity_type" type="int" setter="" getter="">
|
||||||
Type of identity to use. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
Type of identity to use. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
||||||
|
Can be overridden with the environment variable [code]GODOT_WINDOWS_CODESIGN_IDENTITY_TYPE[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="codesign/password" type="String" setter="" getter="">
|
<member name="codesign/password" type="String" setter="" getter="">
|
||||||
Password for the certificate file used to sign executable. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
Password for the certificate file used to sign executable. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
||||||
|
Can be overridden with the environment variable [code]GODOT_WINDOWS_CODESIGN_PASSWORD[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="codesign/timestamp" type="bool" setter="" getter="">
|
<member name="codesign/timestamp" type="bool" setter="" getter="">
|
||||||
If [code]true[/code], time-stamp is added to the signature. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
If [code]true[/code], time-stamp is added to the signature. See [url=https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe]Sign Tool[/url].
|
||||||
|
@ -328,9 +328,9 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
|
|||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm64"), "x86_64"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm64"), "x86_64"));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false, true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA-1 hash)"), 0));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA-1 hash)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), 0));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password", PROPERTY_HINT_PASSWORD), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password", PROPERTY_HINT_PASSWORD, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), ""));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), ""));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1));
|
||||||
@ -518,21 +518,21 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
|
|||||||
|
|
||||||
//identity
|
//identity
|
||||||
#ifdef WINDOWS_ENABLED
|
#ifdef WINDOWS_ENABLED
|
||||||
int id_type = p_preset->get("codesign/identity_type");
|
int id_type = p_preset->get_or_env("codesign/identity_type", ENV_WIN_CODESIGN_ID_TYPE);
|
||||||
if (id_type == 0) { //auto select
|
if (id_type == 0) { //auto select
|
||||||
args.push_back("/a");
|
args.push_back("/a");
|
||||||
} else if (id_type == 1) { //pkcs12
|
} else if (id_type == 1) { //pkcs12
|
||||||
if (p_preset->get("codesign/identity") != "") {
|
if (p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID) != "") {
|
||||||
args.push_back("/f");
|
args.push_back("/f");
|
||||||
args.push_back(p_preset->get("codesign/identity"));
|
args.push_back(p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID));
|
||||||
} else {
|
} else {
|
||||||
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
|
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
} else if (id_type == 2) { //Windows certificate store
|
} else if (id_type == 2) { //Windows certificate store
|
||||||
if (p_preset->get("codesign/identity") != "") {
|
if (p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID) != "") {
|
||||||
args.push_back("/sha1");
|
args.push_back("/sha1");
|
||||||
args.push_back(p_preset->get("codesign/identity"));
|
args.push_back(p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID));
|
||||||
} else {
|
} else {
|
||||||
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
|
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
|
||||||
return FAILED;
|
return FAILED;
|
||||||
@ -543,9 +543,9 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int id_type = 1;
|
int id_type = 1;
|
||||||
if (p_preset->get("codesign/identity") != "") {
|
if (p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID) != "") {
|
||||||
args.push_back("-pkcs12");
|
args.push_back("-pkcs12");
|
||||||
args.push_back(p_preset->get("codesign/identity"));
|
args.push_back(p_preset->get_or_env("codesign/identity", ENV_WIN_CODESIGN_ID));
|
||||||
} else {
|
} else {
|
||||||
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
|
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
|
||||||
return FAILED;
|
return FAILED;
|
||||||
@ -553,13 +553,13 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//password
|
//password
|
||||||
if ((id_type == 1) && (p_preset->get("codesign/password") != "")) {
|
if ((id_type == 1) && (p_preset->get_or_env("codesign/password", ENV_WIN_CODESIGN_PASS) != "")) {
|
||||||
#ifdef WINDOWS_ENABLED
|
#ifdef WINDOWS_ENABLED
|
||||||
args.push_back("/p");
|
args.push_back("/p");
|
||||||
#else
|
#else
|
||||||
args.push_back("-pass");
|
args.push_back("-pass");
|
||||||
#endif
|
#endif
|
||||||
args.push_back(p_preset->get("codesign/password"));
|
args.push_back(p_preset->get_or_env("codesign/password", ENV_WIN_CODESIGN_PASS));
|
||||||
}
|
}
|
||||||
|
|
||||||
//timestamp
|
//timestamp
|
||||||
|
@ -36,6 +36,12 @@
|
|||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
#include "editor/export/editor_export_platform_pc.h"
|
#include "editor/export/editor_export_platform_pc.h"
|
||||||
|
|
||||||
|
// Optional environment variables for defining confidential information. If any
|
||||||
|
// of these is set, they will override the values set in the credentials file.
|
||||||
|
const String ENV_WIN_CODESIGN_ID_TYPE = "GODOT_WINDOWS_CODESIGN_IDENTITY_TYPE";
|
||||||
|
const String ENV_WIN_CODESIGN_ID = "GODOT_WINDOWS_CODESIGN_IDENTITY";
|
||||||
|
const String ENV_WIN_CODESIGN_PASS = "GODOT_WINDOWS_CODESIGN_PASSWORD";
|
||||||
|
|
||||||
class EditorExportPlatformWindows : public EditorExportPlatformPC {
|
class EditorExportPlatformWindows : public EditorExportPlatformPC {
|
||||||
GDCLASS(EditorExportPlatformWindows, EditorExportPlatformPC);
|
GDCLASS(EditorExportPlatformWindows, EditorExportPlatformPC);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user