├── CHANGELOG.md ├── .npmignore ├── .gitignore ├── Samples ├── com.facticus.deploy.samples.asmdef ├── ScenesConfigPreBuild.cs.meta ├── ScenesOverrideVariablesExample.cs.meta ├── Level 1.unity.meta ├── Level 2.unity.meta ├── Level 3.unity.meta ├── SampleScene.unity.meta ├── com.facticus.deploy.samples.asmdef.meta ├── Scenes.asset.meta ├── FloatVariable.asset.meta ├── ScenesOverrideVariablesExample.cs ├── ScenesConfigPreBuild.cs ├── Scenes.asset ├── FloatVariable.asset ├── Level 1.unity ├── Level 2.unity ├── Level 3.unity └── SampleScene.unity ├── Editor ├── Data.meta ├── BackEnds.meta ├── Drawers.meta ├── Resources.meta ├── Settings.meta ├── Utility.meta ├── Versioning.meta ├── BuildPlatforms.meta ├── BuildScript.cs.meta ├── DeployPlatforms.meta ├── EditorWindows.meta ├── NotifyPlatforms.meta ├── VisualElements.meta ├── BackEnds │ ├── Utility.cs.meta │ ├── ActBackend.cs.meta │ ├── GithubActionsBackend.cs.meta │ ├── ICicdBackend.cs │ ├── ICicdBackend.cs.meta │ ├── Utility.cs │ └── ActBackend.cs ├── BuildPreprocessors.meta ├── Drawers │ ├── Resources.meta │ ├── DeployContextEditor.cs.meta │ ├── BuildDeployElementDrawer.cs.meta │ ├── BuildVariableValueDrawer.cs.meta │ ├── DeploySettingsDrawer.cs.meta │ ├── PlayStorePropertyDrawer.cs.meta │ ├── BuildVariableValueDrawer.Preset.cs.meta │ ├── Resources │ │ ├── DeployContextEditor.uss.meta │ │ ├── DeployContextEditor.uxml.meta │ │ ├── DeployContextEditor.uss │ │ └── DeployContextEditor.uxml │ ├── WebglTemplatePreprocessorDrawer.cs.meta │ ├── BuildVariableValueDrawer.ScriptableObject.cs.meta │ ├── WebglTemplatePreprocessorDrawer.cs │ ├── PlayStorePropertyDrawer.cs │ ├── BuildDeployElementDrawer.cs │ ├── DeploySettingsDrawer.cs │ ├── BuildVariableValueDrawer.cs │ ├── BuildVariableValueDrawer.ScriptableObject.cs │ ├── DeployContextEditor.cs │ └── BuildVariableValueDrawer.Preset.cs ├── EditorWindows │ ├── Resources │ │ ├── DeployEditorWindowStyleSheet.uss │ │ ├── DeployEditorWindow.uxml.meta │ │ ├── DeployEditorWindowStyleSheet.uss.meta │ │ └── DeployEditorWindow.uxml │ ├── Resources.meta │ └── DeployEditorWindow.cs.meta ├── Data │ ├── DeployContext.cs.meta │ ├── BuildDeployElement.cs.meta │ ├── BuildVariableValue.cs.meta │ ├── DeployContext.cs │ ├── BuildDeployElement.cs │ └── BuildVariableValue.cs ├── Utility │ ├── EditorUIUtils.cs.meta │ ├── TabBarUtility.cs.meta │ ├── TerminalUtils.cs.meta │ ├── IJsonSerializable.cs.meta │ ├── TokenDialogInput.cs.meta │ ├── DeployContextsListPopulator.cs.meta │ ├── IJsonSerializable.cs │ ├── TokenDialogInput.cs │ ├── EditorUIUtils.cs │ ├── DeployContextsListPopulator.cs │ ├── TabBarUtility.cs │ └── TerminalUtils.cs ├── Settings │ ├── DeploySettings.cs.meta │ ├── DeploySettingsProvider.cs.meta │ ├── WorkflowVersionUpdater.cs.meta │ ├── DeployPersistentSettings.cs.meta │ ├── DeployPersistentSettings.cs │ ├── DeploySettingsProvider.cs │ ├── DeploySettings.cs │ └── WorkflowVersionUpdater.cs ├── Versioning │ ├── VersionGenerator.cs.meta │ ├── VersioningStrategy.cs.meta │ ├── VersioningStrategy.cs │ └── VersionGenerator.cs ├── BuildPlatforms │ ├── IBuildPlatform.cs.meta │ └── IBuildPlatform.cs ├── DeployPlatforms │ ├── IDeployPlatform.cs.meta │ └── IDeployPlatform.cs ├── NotifyPlatforms │ ├── INotifyPlatform.cs.meta │ └── INotifyPlatform.cs ├── Resources │ ├── workflow_template.yml.meta │ └── workflow_template.yml ├── VisualElements │ ├── RenamableLabel.cs.meta │ └── RenamableLabel.cs ├── com.facticus.deploy.editor.asmdef.meta ├── BuildPreprocessors │ ├── WebGLTemplateSelector.meta │ ├── OnDemandBuildPreprocessorWithReport.cs.meta │ ├── WebGLTemplateSelector │ │ ├── SerializableWebGLTemplate.cs.meta │ │ ├── WebglTemplatePreprocessor.cs.meta │ │ ├── SerializableWebGLTemplate.cs │ │ └── WebglTemplatePreprocessor.cs │ └── OnDemandBuildPreprocessorWithReport.cs └── com.facticus.deploy.editor.asmdef ├── .github ├── actions.meta ├── actions │ ├── build.meta │ ├── deploy.meta │ ├── notify.meta │ ├── build │ │ ├── action.yml.meta │ │ └── action.yml │ ├── deploy │ │ ├── telegram.meta │ │ ├── action.yml.meta │ │ ├── telegram │ │ │ ├── action.yml.meta │ │ │ └── action.yml │ │ └── action.yml │ ├── free-disk-space.meta │ ├── get-project-name.meta │ ├── initial-message.meta │ ├── notify │ │ ├── action.yml.meta │ │ └── action.yml │ ├── platform-display-name.meta │ ├── initial-message │ │ ├── action.yml.meta │ │ └── action.yml │ ├── get-project-name │ │ ├── action.yml.meta │ │ ├── getname.sh.meta │ │ ├── getname.sh │ │ └── action.yml │ ├── platform-display-name │ │ ├── action.yml.meta │ │ └── action.yml │ └── free-disk-space │ │ └── action.yml └── workflows │ ├── tests.yml.meta │ ├── only_deploy.yml.meta │ ├── workflow_call.yml.meta │ ├── build_and_deploy.yml.meta │ ├── build_and_deploy.yml │ ├── tests.yml │ ├── workflow_call_json_file.yml │ ├── only_deploy.yml │ └── bump_patch.yml ├── Runtime ├── IntVariable.cs.meta ├── BoolVariable.cs.meta ├── FloatVariable.cs.meta ├── StringVariable.cs.meta ├── com.facticus.deploy.asmdef.meta ├── IntVariable.cs ├── BoolVariable.cs ├── FloatVariable.cs ├── StringVariable.cs └── com.facticus.deploy.asmdef ├── Documentation~ └── com.facticus.deploy.md ├── Tests ├── Editor │ ├── TestScriptableObject.cs.meta │ ├── OverrideVariablesTests.cs.meta │ ├── com.facticus.deploy.EditorTests.asmdef.meta │ ├── com.facticus.deploy.EditorTests.asmdef │ ├── TestScriptableObject.cs │ └── OverrideVariablesTests.cs ├── Editor.meta ├── Runtime.meta └── Runtime │ ├── com.facticus.deploy.Tests.asmdef.meta │ └── com.facticus.deploy.Tests.asmdef ├── LICENSE.meta ├── CHANGELOG.md.meta ├── README.md.meta ├── package.json.meta ├── Editor.meta ├── Runtime.meta ├── Samples.meta ├── Tests.meta ├── package.json └── LICENSE /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Samples 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/** 2 | .vs/** 3 | 4 | -------------------------------------------------------------------------------- /Samples/com.facticus.deploy.samples.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.facticus.deploy.samples" 3 | } 4 | -------------------------------------------------------------------------------- /Editor/Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0509ae7e4af74252980218744fa40599 3 | timeCreated: 1676641195 -------------------------------------------------------------------------------- /.github/actions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5fb1c1f527ba43b49779b8fac8b6067c 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /Editor/BackEnds.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9140c5f9a1524ef1b8656fd35ba511b0 3 | timeCreated: 1687970860 -------------------------------------------------------------------------------- /Editor/Drawers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5803b725004243cf9784f311eec88375 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b1ee7291f6148de9e6a2abfe59a5e25 3 | timeCreated: 1676645867 -------------------------------------------------------------------------------- /Editor/Settings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee80a0f8f53f4fd5a4c253ce486e3f09 3 | timeCreated: 1688496848 -------------------------------------------------------------------------------- /Editor/Utility.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5315da82dd545a0a3cd44172e9fc2a4 3 | timeCreated: 1676641247 -------------------------------------------------------------------------------- /Editor/Versioning.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2fd715c019e44945b7958254c0f80bbf 3 | timeCreated: 1688496272 -------------------------------------------------------------------------------- /.github/actions/build.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46019f4413b146919256d582d2db2b66 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/deploy.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a29cf775c972418782a5c1d7b829ded9 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/notify.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d04a21cbc00349d092b677055fd84e3c 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /Editor/BuildPlatforms.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b057d04fa2a24042be77da93e36f813b 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/BuildScript.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 09a53ee3b0e14a8db37ec7efdc4f83c5 3 | timeCreated: 1682268903 -------------------------------------------------------------------------------- /Editor/DeployPlatforms.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d0659bb865a497e9f678cebc7f40ebc 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/EditorWindows.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9b1e67602394753a27c211a54a76c5e 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/NotifyPlatforms.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 91ea40803a3049c6b98a384cc041f796 3 | timeCreated: 1677425183 -------------------------------------------------------------------------------- /Editor/VisualElements.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 400d83a1f9ca429183b33621ee3082b8 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Runtime/IntVariable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c2ad427f1f448c7b0f2e870f7362ed1 3 | timeCreated: 1682187832 -------------------------------------------------------------------------------- /.github/workflows/tests.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d3b88910f6d7461998ae29a2d72e5cc8 3 | timeCreated: 1724356561 -------------------------------------------------------------------------------- /Editor/BackEnds/Utility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99b8995fa5dc4be989ee1c38d781e2de 3 | timeCreated: 1700498506 -------------------------------------------------------------------------------- /Editor/BuildPreprocessors.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f6038eeea9249dcbde6e37ea8000a72 3 | timeCreated: 1709820876 -------------------------------------------------------------------------------- /Editor/Drawers/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11ae5f731dea40c8afac35923189f32a 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/EditorWindows/Resources/DeployEditorWindowStyleSheet.uss: -------------------------------------------------------------------------------- 1 | #unity-list-view__reorderable-item { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /Runtime/BoolVariable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3656fc0ebb14162b23e7be40012234c 3 | timeCreated: 1682187891 -------------------------------------------------------------------------------- /Runtime/FloatVariable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d34ddad897a741749f538e7f4064f003 3 | timeCreated: 1682187865 -------------------------------------------------------------------------------- /Runtime/StringVariable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 44e0775bf50d43dbbb75456a790249d8 3 | timeCreated: 1682181012 -------------------------------------------------------------------------------- /.github/actions/build/action.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b37de29aa3242a5a2cb62bb4f571892 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/deploy/telegram.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f719a956bf94fdab2da4ed83ef39086 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/free-disk-space.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6ff787c37fe405b82ed65d51a985da1 3 | timeCreated: 1685997578 -------------------------------------------------------------------------------- /.github/actions/get-project-name.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df6ee2713a22441f9309b218e18fc032 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/initial-message.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6ad0b8275bf4ed8b6b2cd3e28a778af 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /Documentation~/com.facticus.deploy.md: -------------------------------------------------------------------------------- 1 | A Unity package to help you build and deploy your game remotely with Github Actions 2 | -------------------------------------------------------------------------------- /Editor/BackEnds/ActBackend.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5b32ed86760440ad9ad69073b741f130 3 | timeCreated: 1687972142 -------------------------------------------------------------------------------- /Editor/Data/DeployContext.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d6228cd6dd744bb8b6bc1150736cb0a 3 | timeCreated: 1676640030 -------------------------------------------------------------------------------- /Editor/EditorWindows/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad91011ceb8b408eb8423070011bc156 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Utility/EditorUIUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0560b3085b5d4a73b2d24f381401a28d 3 | timeCreated: 1709825130 -------------------------------------------------------------------------------- /Editor/Utility/TabBarUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9bbf348dda4847799508b1a9cd0d494e 3 | timeCreated: 1676919847 -------------------------------------------------------------------------------- /Editor/Utility/TerminalUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf60ff375a824f42bd1cf87392fcc182 3 | timeCreated: 1687971443 -------------------------------------------------------------------------------- /Samples/ScenesConfigPreBuild.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bee986329cc54a5584c4323d9991bd22 3 | timeCreated: 1699056381 -------------------------------------------------------------------------------- /.github/actions/deploy/action.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb479a16ab77425cad7d6bcf48ee295a 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/notify/action.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f26ccc41d0e4aa0b06191fad0bf9423 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/platform-display-name.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: daa9d0c083644f08b473caccd930f330 3 | timeCreated: 1682268642 -------------------------------------------------------------------------------- /.github/workflows/only_deploy.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b9ecc3e12ed48a2a216a705c7321f82 3 | timeCreated: 1687962642 -------------------------------------------------------------------------------- /.github/workflows/workflow_call.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae3f46c59da344598ff58ce8f1fc87df 3 | timeCreated: 1681683331 -------------------------------------------------------------------------------- /Editor/Data/BuildDeployElement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0df9d50607e45bdb23d8880cc4df9c5 3 | timeCreated: 1676640029 -------------------------------------------------------------------------------- /Editor/Data/BuildVariableValue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bdcd0f4759ee405bad77e59743ad766b 3 | timeCreated: 1682187716 -------------------------------------------------------------------------------- /Editor/Drawers/DeployContextEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a1894b85c4742559722967abb7f8076 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Settings/DeploySettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5b80c7c2b6784211a13f23bbafb0e6bd 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Utility/IJsonSerializable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3e654e37452341eebbedbc1805132c13 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Utility/TokenDialogInput.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d50c1ad696534517b995f5d7bac94f9f 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Versioning/VersionGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68a9014647fd4d5782a3cdccc6ba2dd0 3 | timeCreated: 1688496719 -------------------------------------------------------------------------------- /Tests/Editor/TestScriptableObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83990066ea514561a44cbf1164361ee4 3 | timeCreated: 1746472837 -------------------------------------------------------------------------------- /.github/actions/deploy/telegram/action.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50cc644c4a77496a8a1dbb84fee2b5d8 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/initial-message/action.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d31bc45f6f5f48eea6be2938dd61c33d 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/workflows/build_and_deploy.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cffa4f5de5a041f7bc3c9981b8ce0550 3 | timeCreated: 1682271697 -------------------------------------------------------------------------------- /Editor/BackEnds/GithubActionsBackend.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 217feb9460c24587946f5c78c6709230 3 | timeCreated: 1687970954 -------------------------------------------------------------------------------- /Editor/BuildPlatforms/IBuildPlatform.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9fa56f56edc488b915438796e189f40 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/DeployPlatforms/IDeployPlatform.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f2835147e144007a35ce3f597480232 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Drawers/BuildDeployElementDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a77a934bb1b24e97812865cf91f54524 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Drawers/BuildVariableValueDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e5dd87b1075490aabeb1be7286879df 3 | timeCreated: 1682191061 -------------------------------------------------------------------------------- /Editor/Drawers/DeploySettingsDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6bd33b9bcc0545fc85348b5c7b4e49b7 3 | timeCreated: 1676644799 -------------------------------------------------------------------------------- /Editor/Drawers/PlayStorePropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 869ff4d09c974c5889da333c87df29c3 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/EditorWindows/DeployEditorWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: efd711c9ff534aefb873d8727da87139 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/NotifyPlatforms/INotifyPlatform.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c82c873274104c70aba718a6f266c480 3 | timeCreated: 1677425194 -------------------------------------------------------------------------------- /Editor/Resources/workflow_template.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 047b8a73a7ef465985932a0f0e83d6f0 3 | timeCreated: 1681683110 -------------------------------------------------------------------------------- /Editor/Settings/DeploySettingsProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 21b52acdd5584a2899cac99899260676 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Settings/WorkflowVersionUpdater.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fa7d892f2fe489ba6ad0b4684cba7a6 3 | timeCreated: 1690831223 -------------------------------------------------------------------------------- /Editor/Versioning/VersioningStrategy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 948b684db5be47c2ade0ad627219083c 3 | timeCreated: 1688496296 -------------------------------------------------------------------------------- /Editor/VisualElements/RenamableLabel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 410c4d9943c44888955dcc2061bfe6f6 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/com.facticus.deploy.editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4550b8028c94adf9a90ce699ae4ad99 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Samples/ScenesOverrideVariablesExample.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f5e3ce8367f4c9e958dad02c77413ce 3 | timeCreated: 1699055492 -------------------------------------------------------------------------------- /Tests/Editor/OverrideVariablesTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 849e9c218c6447e387f7fd440e718c1d 3 | timeCreated: 1710421552 -------------------------------------------------------------------------------- /.github/actions/get-project-name/action.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8bedcdddb9e041cc8f86a2ee7fd03fa1 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /.github/actions/get-project-name/getname.sh.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7aaf199c2a2049d49ec3528c9f320ff9 3 | timeCreated: 1682268641 -------------------------------------------------------------------------------- /Editor/BuildPreprocessors/WebGLTemplateSelector.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: efcd78dca2ba41b6804683278ba31bbc 3 | timeCreated: 1709821871 -------------------------------------------------------------------------------- /Editor/Settings/DeployPersistentSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 944cdb0ce5a64bdc8778f45159c66893 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Utility/DeployContextsListPopulator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43b920de5f7744798361ee4be84cf5e0 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /.github/actions/platform-display-name/action.yml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83d51d357adc43ba924bcb1e5475960b 3 | timeCreated: 1682268642 -------------------------------------------------------------------------------- /Editor/Drawers/BuildVariableValueDrawer.Preset.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b524c1e32ac7466c8b8c2678bcc34e9a 3 | timeCreated: 1710432112 -------------------------------------------------------------------------------- /Editor/Drawers/Resources/DeployContextEditor.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a66b857774642729bb5572d33e07698 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Drawers/Resources/DeployContextEditor.uxml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b62791e82c44ce1a78a2ef8f16324cd 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Drawers/WebglTemplatePreprocessorDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1515786fb8b4fe1a56d17dcead788ad 3 | timeCreated: 1709826513 -------------------------------------------------------------------------------- /Editor/Drawers/Resources/DeployContextEditor.uss: -------------------------------------------------------------------------------- 1 | Label { 2 | font-size: 20px; 3 | -unity-font-style: bold; 4 | color: rgb(68, 138, 255); 5 | } -------------------------------------------------------------------------------- /Editor/EditorWindows/Resources/DeployEditorWindow.uxml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 25c42cdc866c4f3fb58c1a719c855e21 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/Drawers/BuildVariableValueDrawer.ScriptableObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 538aa4be07a44f2e8d8a4f1469dff238 3 | timeCreated: 1710432093 -------------------------------------------------------------------------------- /Editor/BuildPreprocessors/OnDemandBuildPreprocessorWithReport.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad72a09c253e47db8c642faac759ad08 3 | timeCreated: 1709820926 -------------------------------------------------------------------------------- /Editor/EditorWindows/Resources/DeployEditorWindowStyleSheet.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15902b6ea0ca44b6ab60f426d9cb11dd 3 | timeCreated: 1676640031 -------------------------------------------------------------------------------- /Editor/BuildPreprocessors/WebGLTemplateSelector/SerializableWebGLTemplate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83c99f7978a148b8a618fc5854c9d6c9 3 | timeCreated: 1709821874 -------------------------------------------------------------------------------- /Editor/BuildPreprocessors/WebGLTemplateSelector/WebglTemplatePreprocessor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a75fb9bc94d4db4858f61104e700226 3 | timeCreated: 1709821874 -------------------------------------------------------------------------------- /Editor/Utility/IJsonSerializable.cs: -------------------------------------------------------------------------------- 1 | namespace Deploy.Editor.Utility 2 | { 3 | public interface IJsonSerializable 4 | { 5 | string ToJson(); 6 | } 7 | } -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 734a97a7556589e49861bb1c28d54799 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 889c5186f7d282547bdf596d7bbf5c2a 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/Versioning/VersioningStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace Deploy.Editor.Versioning 2 | { 3 | public enum VersioningStrategy 4 | { 5 | Semantic, 6 | Tag, 7 | None 8 | } 9 | } -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48cc2af6f8ee4964b9ac544d19d9daec 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 07d748946bb1fec43844f41e485197bc 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /.github/actions/get-project-name/getname.sh: -------------------------------------------------------------------------------- 1 | while IFS=: read -r key value 2 | do 3 | if [[ $key == " productName" ]] 4 | then 5 | echo $value; 6 | fi 7 | done < "ProjectSettings/ProjectSettings.asset" -------------------------------------------------------------------------------- /Samples/Level 1.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac4610da5508109448e15cb3d283e003 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples/Level 2.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8ad65d5a2b25a994e959b165324580c5 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples/Level 3.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4ee2d0d6d3160f74caa2886cd6d7e8a8 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1bec453c316d42e43aa5a80dac44d53d 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7474a12f5990cc547b337acb82ff3671 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57608cb8fbc72b547987ff573135e629 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: add3f964baf254e4b9e2dd94234d9781 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b575eb76a2086e478a52485ed0e3cca 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63f02074e5dea33409455fcc816a31ec 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf350fa842fee4241a3d53fafd4c0f8a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/com.facticus.deploy.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd8731eefd9c3244ebcecf27d19df7e7 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples/com.facticus.deploy.samples.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba5192bb36a72fc4dac4f7e3f209c66f 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples/Scenes.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f57553495c1a6a4186837bc814202b0 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/Runtime/com.facticus.deploy.Tests.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7c82f622bb1bfb94a97db50b23aabf38 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples/FloatVariable.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73e9d0430ced7ff4aad35ad8ab803250 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 11400000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/Editor/com.facticus.deploy.EditorTests.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 692aa5d2f6c21814e82953e7c5175b07 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/BackEnds/ICicdBackend.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Deploy.Editor.Data; 3 | 4 | namespace Deploy.Editor.BackEnds 5 | { 6 | public interface ICicdBackend 7 | { 8 | Task BuildAndDeploy(DeployContext context); 9 | } 10 | } -------------------------------------------------------------------------------- /Editor/Utility/TokenDialogInput.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Deploy.Editor.Utility 4 | { 5 | internal class TokenDialogInput : ScriptableObject 6 | { 7 | [SerializeField] private string _authToken; 8 | 9 | public string AuthToken => _authToken; 10 | } 11 | } -------------------------------------------------------------------------------- /Editor/BackEnds/ICicdBackend.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 043e48cc33d8404bbf237dfaad3c929a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples/ScenesOverrideVariablesExample.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using UnityEditor; 4 | 5 | namespace Deploy.Samples 6 | { 7 | public class ScenesOverrideVariablesExample : ScriptableObject 8 | { 9 | #if UNITY_EDITOR 10 | [SerializeField] private List _scenes; 11 | #endif 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/IntVariable.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Deploy.Runtime 4 | { 5 | [CreateAssetMenu(fileName = "IntVariable", menuName = "Facticus/Deploy/IntVariable", order = 0)] 6 | public class IntVariable : ScriptableObject 7 | { 8 | [SerializeField] private int _value; 9 | 10 | public int Value => _value; 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/BoolVariable.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Deploy.Runtime 4 | { 5 | [CreateAssetMenu(fileName = "BoolVariable", menuName = "Facticus/Deploy/BoolVariable", order = 0)] 6 | public class BoolVariable : ScriptableObject 7 | { 8 | [SerializeField] private bool _value; 9 | 10 | public bool Value => _value; 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/FloatVariable.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Deploy.Runtime 4 | { 5 | [CreateAssetMenu(fileName = "FloatVariable", menuName = "Facticus/Deploy/FloatVariable", order = 0)] 6 | public class FloatVariable : ScriptableObject 7 | { 8 | [SerializeField] private float _value; 9 | 10 | public float Value => _value; 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/StringVariable.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Deploy.Runtime 4 | { 5 | [CreateAssetMenu(fileName = "StringVariable", menuName = "Facticus/Deploy/StringVariable", order = 0)] 6 | public class StringVariable : ScriptableObject 7 | { 8 | [SerializeField] private string _value; 9 | 10 | public string Value => _value; 11 | } 12 | } -------------------------------------------------------------------------------- /.github/workflows/build_and_deploy.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | json_parameters: 7 | type: string 8 | required: true 9 | 10 | jobs: 11 | run: 12 | uses: mnicolas94/facticus-deploy/.github/workflows/workflow_call.yml@v0.6.36 13 | with: 14 | json_parameters: ${{ inputs.json_parameters }} 15 | secrets: inherit -------------------------------------------------------------------------------- /Samples/ScenesConfigPreBuild.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | 3 | using UnityEditor.Build; 4 | using UnityEditor.Build.Reporting; 5 | 6 | namespace Deploy.Samples 7 | { 8 | public class ScenesConfigPreBuild : IPreprocessBuildWithReport 9 | { 10 | public int callbackOrder => 0; 11 | 12 | public void OnPreprocessBuild(BuildReport report) 13 | { 14 | // configurar escenas 15 | } 16 | } 17 | } 18 | 19 | #endif -------------------------------------------------------------------------------- /Editor/Settings/DeployPersistentSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.Scripting.APIUpdating; 4 | 5 | namespace Deploy.Editor.Settings 6 | { 7 | [Serializable] 8 | [MovedFrom("Deploy.Editor")] 9 | internal class DeployPersistentSettings 10 | { 11 | [SerializeField] private string _githubAuthToken; 12 | 13 | public string GithubAuthToken 14 | { 15 | get => _githubAuthToken; 16 | set => _githubAuthToken = value; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Runtime/com.facticus.deploy.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.facticus.deploy", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:c35c6d9084ba1a541868fbd8c50a585a", 6 | "GUID:87f0d0b9a8d159a4c94e89b339e4604a", 7 | "GUID:49b49c76ee64f6b41bf28ef951cb0e50" 8 | ], 9 | "includePlatforms": [], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Editor/NotifyPlatforms/INotifyPlatform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Deploy.Editor.NotifyPlatforms 4 | { 5 | public interface INotifyPlatform 6 | { 7 | string GetPlatformName(); 8 | } 9 | 10 | [Serializable] 11 | [AddTypeMenu("Telegram")] 12 | public class TelegramNotifyPlatform : INotifyPlatform 13 | { 14 | public string GetPlatformName() => "Telegram"; 15 | } 16 | 17 | [Serializable] 18 | [AddTypeMenu("Discord")] 19 | public class DiscordNotifyPlatform : INotifyPlatform 20 | { 21 | public string GetPlatformName() => "Discord"; 22 | } 23 | } -------------------------------------------------------------------------------- /Tests/Runtime/com.facticus.deploy.Tests.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.facticus.deploy.Tests", 3 | "rootNamespace": "", 4 | "references": [ 5 | "com.facticus.deploy", 6 | "UnityEngine.TestRunner", 7 | "UnityEditor.TestRunner" 8 | ], 9 | "includePlatforms": [], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": true, 13 | "precompiledReferences": [ 14 | "nunit.framework.dll" 15 | ], 16 | "autoReferenced": false, 17 | "defineConstraints": [ 18 | "UNITY_INCLUDE_TESTS" 19 | ], 20 | "versionDefines": [], 21 | "noEngineReferences": false 22 | } -------------------------------------------------------------------------------- /Samples/Scenes.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: 4f5e3ce8367f4c9e958dad02c77413ce, type: 3} 13 | m_Name: Scenes 14 | m_EditorClassIdentifier: 15 | _scenes: 16 | - {fileID: 102900000, guid: ac4610da5508109448e15cb3d283e003, type: 3} 17 | - {fileID: 102900000, guid: 8ad65d5a2b25a994e959b165324580c5, type: 3} 18 | - {fileID: 102900000, guid: 4ee2d0d6d3160f74caa2886cd6d7e8a8, type: 3} 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.facticus.deploy", 3 | "version": "0.6.36", 4 | "displayName": "Deploy", 5 | "description": "A Unity package to help you build and deploy your game remotely with Github Actions", 6 | "unity": "2021.3", 7 | "unityRelease": "", 8 | "dependencies": { 9 | "com.facticus.utils": "0.13.4", 10 | "com.mackysoft.serializereference-extensions": "1.3.0", 11 | "com.unity.nuget.newtonsoft-json": "3.2.1" 12 | }, 13 | "keywords": [], 14 | "author": { 15 | "name": "Facticus", 16 | "email": "", 17 | "url": "" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/mnicolas94/facticus-deploy.git" 22 | }, 23 | "license": "MIT" 24 | } -------------------------------------------------------------------------------- /Tests/Editor/com.facticus.deploy.EditorTests.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.facticus.deploy.Editor.Tests", 3 | "rootNamespace": "", 4 | "references": [ 5 | "com.facticus.deploy", 6 | "com.facticus.deploy.editor", 7 | "UnityEngine.TestRunner", 8 | "UnityEditor.TestRunner" 9 | ], 10 | "includePlatforms": [ 11 | "Editor" 12 | ], 13 | "excludePlatforms": [], 14 | "allowUnsafeCode": false, 15 | "overrideReferences": true, 16 | "precompiledReferences": [ 17 | "nunit.framework.dll" 18 | ], 19 | "autoReferenced": false, 20 | "defineConstraints": [ 21 | "UNITY_INCLUDE_TESTS" 22 | ], 23 | "versionDefines": [], 24 | "noEngineReferences": false 25 | } -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | bool: 8 | type: boolean 9 | required: true 10 | description: "" 11 | 12 | jobs: 13 | test: 14 | name: test 15 | runs-on: ubuntu-latest 16 | if: ${{ inputs.bool }} 17 | steps: 18 | - name: run if boolean 19 | if: ${{ inputs.bool }} 20 | run: | 21 | echo bool is true 22 | 23 | - name: run if boolean 24 | if: ${{ !inputs.bool }} 25 | run: | 26 | echo bool is false 27 | 28 | depends: 29 | name: depends 30 | runs-on: ubuntu-latest 31 | needs: [test] 32 | steps: 33 | - name: echo 34 | run: | 35 | echo depends ran -------------------------------------------------------------------------------- /.github/actions/get-project-name/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Get Unity project name' 2 | description: 'Get Unity project name' 3 | outputs: 4 | projectName: 5 | description: "Project name" 6 | value: ${{ steps.project_name.outputs.projectName }} 7 | projectNameNoSpaces: 8 | description: "Project name with underscores instead of spaces" 9 | value: ${{ steps.project_name.outputs.projectNameNoSpaces }} 10 | runs: 11 | using: "composite" 12 | steps: 13 | - name: Get project name variable 14 | id: project_name 15 | shell: bash 16 | run: | 17 | chmod +x ${{ github.action_path }}/getname.sh 18 | projectname=$(${{ github.action_path }}/getname.sh) 19 | projectnamenospaces=${projectname// /_} 20 | echo "projectName=$projectname" >> $GITHUB_OUTPUT 21 | echo "projectNameNoSpaces=$projectnamenospaces" >> $GITHUB_OUTPUT 22 | -------------------------------------------------------------------------------- /Editor/Utility/EditorUIUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using UnityEditor.UIElements; 4 | using UnityEngine.UIElements; 5 | 6 | namespace Deploy.Editor.Utility 7 | { 8 | public static class EditorUIUtils 9 | { 10 | public static async Task GetChildFromPropertyFieldAsync(PropertyField propertyField) 11 | where T : VisualElement 12 | { 13 | var cts = new CancellationTokenSource(1000); 14 | var ct = cts.Token; 15 | 16 | while (!ct.IsCancellationRequested) 17 | { 18 | var list = propertyField.Q(); 19 | if (list != null) 20 | { 21 | return list; 22 | } 23 | 24 | await Task.Yield(); 25 | } 26 | 27 | return null; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Tests/Editor/TestScriptableObject.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Deploy.Tests.Editor 4 | { 5 | public class TestScriptableObject : ScriptableObject 6 | { 7 | public int Int; 8 | public float Float; 9 | public string String; 10 | 11 | public static TestScriptableObject Get(int i = 0, float f = 0f, string s = "") 12 | { 13 | var tso = CreateInstance(); 14 | tso.Int = i; 15 | tso.Float = f; 16 | tso.String = s; 17 | return tso; 18 | } 19 | 20 | public bool IsEqualTo(TestScriptableObject other) 21 | { 22 | if (Int != other.Int) return false; 23 | if (!Mathf.Approximately(Float, other.Float)) return false; 24 | if (String != other.String) return false; 25 | 26 | return true; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Editor/Drawers/Resources/DeployContextEditor.uxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Editor/com.facticus.deploy.editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.facticus.deploy.editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:fd8731eefd9c3244ebcecf27d19df7e7", 6 | "GUID:c35c6d9084ba1a541868fbd8c50a585a", 7 | "GUID:87f0d0b9a8d159a4c94e89b339e4604a", 8 | "GUID:49b49c76ee64f6b41bf28ef951cb0e50", 9 | "GUID:9e24947de15b9834991c9d8411ea37cf", 10 | "GUID:69448af7b92c7f342b298e06a37122aa" 11 | ], 12 | "includePlatforms": [ 13 | "Editor" 14 | ], 15 | "excludePlatforms": [], 16 | "allowUnsafeCode": false, 17 | "overrideReferences": false, 18 | "precompiledReferences": [], 19 | "autoReferenced": true, 20 | "defineConstraints": [], 21 | "versionDefines": [ 22 | { 23 | "name": "com.unity.addressables", 24 | "expression": "1.0.0", 25 | "define": "ENABLED_ADDRESSABLES" 26 | } 27 | ], 28 | "noEngineReferences": false 29 | } -------------------------------------------------------------------------------- /.github/actions/notify/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Notify' 2 | description: 'Send a message' 3 | inputs: 4 | notifyPlatform: 5 | required: true 6 | description: 'Platform to send the message.' 7 | message: 8 | required: true 9 | description: 'Message to send' 10 | 11 | runs: 12 | using: "composite" 13 | steps: 14 | # Telegram 15 | - name: Send notification to Telegram 16 | if: ${{ inputs.notifyPlatform == 'Telegram'}} 17 | uses: appleboy/telegram-action@master 18 | with: 19 | to: ${{ env.TELEGRAM_CHAT_ID }} 20 | token: ${{ env.TELEGRAM_TOKEN }} 21 | message: ${{ inputs.message }} 22 | 23 | # Discord 24 | - name: Send notification to Discord 25 | if: ${{ inputs.notifyPlatform == 'Discord'}} 26 | uses: appleboy/discord-action@master 27 | with: 28 | webhook_id: ${{ env.DISCORD_WEBHOOK_ID }} 29 | webhook_token: ${{ env.DISCORD_WEBHOOK_TOKEN }} 30 | message: ${{ inputs.message }} 31 | -------------------------------------------------------------------------------- /.github/actions/platform-display-name/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Get platform display name' 2 | description: 'Get a nice/display name for a GameCI platform' 3 | inputs: 4 | platform: 5 | required: true 6 | outputs: 7 | display_name: 8 | value: ${{ steps.get_name.outputs.display_name }} 9 | display_name_lower: 10 | value: ${{ steps.get_name.outputs.display_name_lower }} 11 | 12 | runs: 13 | using: "composite" 14 | steps: 15 | - name: Get GameCI platforms display name 16 | id: get_name 17 | env: 18 | StandaloneWindows64: "Windows" 19 | StandaloneLinux64: "Linux" 20 | StandaloneOSX: "Mac" 21 | Android: "Android" 22 | WebGL: "WebGL" 23 | StandaloneWindows64_lower: "windows" 24 | StandaloneLinux64_lower: "linux" 25 | StandaloneOSX_lower: "mac" 26 | Android_lower: "android" 27 | WebGL_lower: "webgl" 28 | shell: bash 29 | run: | 30 | echo "display_name=${{ env[format('{0}', inputs.platform)] }}" >> $GITHUB_OUTPUT 31 | echo "display_name_lower=${{ env[format('{0}_lower', inputs.platform)] }}" >> $GITHUB_OUTPUT 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Facticus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Editor/Settings/DeploySettingsProvider.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEditor.UIElements; 3 | using UnityEngine.UIElements; 4 | 5 | namespace Deploy.Editor.Settings 6 | { 7 | public static class DeploySettingsProvider 8 | { 9 | [SettingsProvider] 10 | public static SettingsProvider GetSettingsProvider() 11 | { 12 | var settings = DeploySettings.GetOrCreate(); 13 | SerializedObject so = new SerializedObject(settings); 14 | var keywords = SettingsProvider.GetSearchKeywordsFromSerializedObject(so); 15 | 16 | var provider = new SettingsProvider("Project/Facticus/Deploy", SettingsScope.Project) 17 | { 18 | activateHandler = (searchContext, root) => 19 | { 20 | var inspector = new InspectorElement(settings); 21 | var scroll = new ScrollView(ScrollViewMode.Vertical); 22 | scroll.Add(inspector); 23 | root.Add(scroll); 24 | }, 25 | keywords = keywords 26 | }; 27 | 28 | return provider; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /.github/actions/initial-message/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Send first notification message' 2 | description: 'Send message to telegram notifying some build process has started' 3 | inputs: 4 | development_build: 5 | description: 'The build is a development one' 6 | required: true 7 | platform: 8 | description: "From which platform is the build" 9 | required: true 10 | bot-token: 11 | description: 'Token of the bot that will send the file' 12 | required: true 13 | chat-id: 14 | description: 'Id of the chat to send the file' 15 | required: true 16 | runs: 17 | using: "composite" 18 | steps: 19 | - name: Get version variable 20 | id: version 21 | shell: bash 22 | run: | 23 | echo "lasttag=$(git describe --tags --abbrev=0)" >> $GITHUB_OUTPUT 24 | - name: Get project name variable 25 | id: project_name 26 | uses: mnicolas94/facticus-deploy/.github/actions/get-project-name@v0.6.36 27 | - uses: appleboy/telegram-action@master 28 | env: 29 | message_verb: ${{ fromJSON('["release", "devbuild"]')[inputs.development_build == 'true'] }} 30 | with: 31 | to: ${{ inputs.chat-id }} 32 | token: ${{ inputs.bot-token }} 33 | message: "#${{ inputs.platform }} #${{ env.message_verb }} #${{ steps.project_name.outputs.projectName }} ${{ steps.version.outputs.lasttag }}." 34 | -------------------------------------------------------------------------------- /Samples/FloatVariable.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!181963792 &-705526295798685442 4 | Preset: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: FloatVariable.New Context 10 | m_TargetType: 11 | m_NativeTypeID: 114 12 | m_ManagedTypePPtr: {fileID: 11500000, guid: d34ddad897a741749f538e7f4064f003, type: 3} 13 | m_ManagedTypeFallback: 14 | m_Properties: 15 | - target: {fileID: 0} 16 | propertyPath: m_Enabled 17 | value: 1 18 | objectReference: {fileID: 0} 19 | - target: {fileID: 0} 20 | propertyPath: m_EditorHideFlags 21 | value: 0 22 | objectReference: {fileID: 0} 23 | - target: {fileID: 0} 24 | propertyPath: m_EditorClassIdentifier 25 | value: 26 | objectReference: {fileID: 0} 27 | - target: {fileID: 0} 28 | propertyPath: _value 29 | value: 56 30 | objectReference: {fileID: 0} 31 | m_ExcludedProperties: [] 32 | --- !u!114 &11400000 33 | MonoBehaviour: 34 | m_ObjectHideFlags: 0 35 | m_CorrespondingSourceObject: {fileID: 0} 36 | m_PrefabInstance: {fileID: 0} 37 | m_PrefabAsset: {fileID: 0} 38 | m_GameObject: {fileID: 0} 39 | m_Enabled: 1 40 | m_EditorHideFlags: 0 41 | m_Script: {fileID: 11500000, guid: d34ddad897a741749f538e7f4064f003, type: 3} 42 | m_Name: FloatVariable 43 | m_EditorClassIdentifier: 44 | _value: 0 45 | -------------------------------------------------------------------------------- /Editor/BuildPreprocessors/OnDemandBuildPreprocessorWithReport.cs: -------------------------------------------------------------------------------- 1 | using Deploy.Editor.Settings; 2 | using UnityEditor.Build; 3 | using UnityEditor.Build.Reporting; 4 | 5 | namespace Deploy.Editor.BuildPreprocessors 6 | { 7 | public interface IOnDemandBuildPreprocessorWithReport 8 | { 9 | void OnValidate(); 10 | } 11 | 12 | public abstract class OnDemandBuildPreprocessorWithReport : IPreprocessBuildWithReport, IOnDemandBuildPreprocessorWithReport 13 | { 14 | public bool IsEnabled 15 | { 16 | get 17 | { 18 | var enabledPreprocessors = DeploySettings.GetOrCreate().OnDemandBuildPreprocessors; 19 | foreach (var enabledPreprocessor in enabledPreprocessors) 20 | { 21 | if (enabledPreprocessor != null && enabledPreprocessor.GetType() == GetType()) 22 | { 23 | return true; 24 | } 25 | } 26 | 27 | return false; 28 | } 29 | } 30 | 31 | public int callbackOrder { get; } 32 | public void OnPreprocessBuild(BuildReport report) 33 | { 34 | if (IsEnabled) 35 | { 36 | OnPreprocessBuildInternal(report); 37 | } 38 | } 39 | 40 | protected abstract void OnPreprocessBuildInternal(BuildReport report); 41 | public abstract void OnValidate(); 42 | } 43 | } -------------------------------------------------------------------------------- /Editor/BuildPreprocessors/WebGLTemplateSelector/SerializableWebGLTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEngine; 3 | using Utils.Attributes; 4 | 5 | namespace Deploy.Editor.BuildPreprocessors.WebGLTemplateSelector 6 | { 7 | public class SerializableWebGLTemplate : ScriptableObject 8 | { 9 | [SerializeField, Dropdown(nameof(GetTemplates))] private string _template = "APPLICATION:Default"; 10 | public string Template => _template; 11 | 12 | private DropdownList GetTemplates() 13 | { 14 | var templates = new DropdownList(); 15 | 16 | templates.Add("Default", "APPLICATION:Default"); 17 | templates.Add("Minimal", "APPLICATION:Minimal"); 18 | templates.Add("PWA", "APPLICATION:PWA"); 19 | 20 | var customTemplatesDirectory = "Assets/WebGLTemplates/"; 21 | if (Directory.Exists(customTemplatesDirectory)) 22 | { 23 | var templatesDirs = Directory.GetDirectories(customTemplatesDirectory); 24 | foreach (var templateDir in templatesDirs) 25 | { 26 | var fullPath = Path.GetFullPath(templateDir); 27 | var splits = fullPath.Split(Path.DirectorySeparatorChar); 28 | var templateName = splits[^1]; 29 | templates.Add(templateName, $"PROJECT:{templateName}"); 30 | } 31 | } 32 | 33 | return templates; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Editor/Data/DeployContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | using UnityEngine; 4 | using UnityEngine.Scripting.APIUpdating; 5 | using UnityEngine.Serialization; 6 | 7 | namespace Deploy.Editor.Data 8 | { 9 | [CreateAssetMenu(fileName = "DeployContext", menuName = "Facticus/Deploy/DeployContext", order = 0)] 10 | [MovedFrom(false, null, null, sourceClassName: "BuildDeploySet")] 11 | public class DeployContext : ScriptableObject 12 | { 13 | [FormerlySerializedAs("_repositoryBranch")] [SerializeField] 14 | private string _repositoryBranchOrTag; 15 | 16 | [FormerlySerializedAs("_variables")] [SerializeField] 17 | private List _overrideVariables; 18 | 19 | [FormerlySerializedAs("_elements")] [SerializeField] 20 | private List _platforms; 21 | 22 | public ReadOnlyCollection OverrideVariables => _overrideVariables.AsReadOnly(); 23 | 24 | public ReadOnlyCollection Platforms => _platforms.AsReadOnly(); 25 | 26 | public string RepositoryBranchOrTag => _repositoryBranchOrTag; 27 | 28 | public bool AllDisabled => _platforms.TrueForAll(element => !element.Enabled); 29 | 30 | #if UNITY_EDITOR 31 | [ContextMenu(nameof(ChangeToPresetMode))] 32 | private void ChangeToPresetMode() 33 | { 34 | foreach (var variableValue in _overrideVariables) 35 | { 36 | variableValue.Editor_ChangeToPresetMode(this); 37 | } 38 | } 39 | #endif 40 | } 41 | } -------------------------------------------------------------------------------- /Editor/BuildPlatforms/IBuildPlatform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Deploy.Editor.BuildPlatforms 5 | { 6 | public interface IBuildPlatform 7 | { 8 | string GetGameCiName(); 9 | } 10 | 11 | [Serializable] 12 | [AddTypeMenu("Dummy (does not build, only for tests)")] 13 | public class Dummy : IBuildPlatform 14 | { 15 | public string GetGameCiName() => "Dummy"; 16 | 17 | [SerializeField] private string dummyDirectory; 18 | } 19 | 20 | [Serializable] 21 | public class Windows : IBuildPlatform 22 | { 23 | public string GetGameCiName() => "StandaloneWindows64"; 24 | } 25 | 26 | [Serializable] 27 | public class Linux : IBuildPlatform 28 | { 29 | public string GetGameCiName() => "StandaloneLinux64"; 30 | } 31 | 32 | [Serializable] 33 | public class Mac : IBuildPlatform 34 | { 35 | public string GetGameCiName() => "StandaloneOSX"; 36 | 37 | [SerializeField, Tooltip("Whether to add executable permissions to the app")] 38 | private bool macAddPermissions = true; 39 | } 40 | 41 | [Serializable] 42 | public class Android : IBuildPlatform 43 | { 44 | public string GetGameCiName() => "Android"; 45 | 46 | [SerializeField, Tooltip("Set this flag to true to build '.aab' instead of '.apk'")] 47 | private bool appBundle; 48 | 49 | public bool AppBundle => appBundle; 50 | } 51 | 52 | [Serializable] 53 | public class WebGL : IBuildPlatform 54 | { 55 | public string GetGameCiName() => "WebGL"; 56 | } 57 | } -------------------------------------------------------------------------------- /Editor/Data/BuildDeployElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Deploy.Editor.BuildPlatforms; 3 | using Deploy.Editor.DeployPlatforms; 4 | using UnityEngine; 5 | 6 | namespace Deploy.Editor.Data 7 | { 8 | [Serializable] 9 | public class BuildDeployElement 10 | { 11 | [SerializeField, HideInInspector] private bool _enabled = true; 12 | [SerializeField] private bool _developmentBuild; 13 | [SerializeField] 14 | [Tooltip("Whether to free disk space in the runner that builds your project before the build starts. " + 15 | "Not applicable to local builds with Act backend. Only set it to true if you are getting a " + 16 | "\"...no space left on device.\" error.")] 17 | private bool _freeDiskSpaceBeforeBuild; 18 | [SerializeReference, SubclassSelector] private IBuildPlatform _buildPlatform; 19 | [SerializeReference, SubclassSelector] private IDeployPlatform _deployPlatform; 20 | // [SerializeField] private SubclassSelector _deployPlatformCustom; 21 | 22 | public bool Enabled => _enabled; 23 | 24 | public bool DevelopmentBuild => _developmentBuild; 25 | 26 | public bool FreeDiskSpaceBeforeBuild => _freeDiskSpaceBeforeBuild; 27 | 28 | public IBuildPlatform BuildPlatform 29 | { 30 | get => _buildPlatform; 31 | set => _buildPlatform = value; 32 | } 33 | 34 | public IDeployPlatform DeployPlatform 35 | { 36 | get => _deployPlatform; 37 | set => _deployPlatform = value; 38 | } 39 | 40 | public override string ToString() 41 | { 42 | return $"{_buildPlatform.GetGameCiName()} -> {_deployPlatform.GetPlatformName()}"; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Editor/Drawers/WebglTemplatePreprocessorDrawer.cs: -------------------------------------------------------------------------------- 1 | using Deploy.Editor.BuildPreprocessors.WebGLTemplateSelector; 2 | using UnityEditor; 3 | using UnityEngine; 4 | using Utils.Editor; 5 | 6 | namespace Deploy.Editor.Drawers 7 | { 8 | [CustomPropertyDrawer(typeof(WebglTemplatePreprocessor))] 9 | public class WebglTemplatePreprocessorDrawer : PropertyDrawer 10 | { 11 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 12 | { 13 | EditorGUI.BeginProperty(position, label, property); 14 | EditorGUI.BeginDisabledGroup(true); 15 | 16 | var childrenProperties = PropertiesUtils.GetSerializedProperties(property); 17 | 18 | var yOffset = 0f; 19 | foreach (var childrenProperty in childrenProperties) 20 | { 21 | var rect = new Rect(position); 22 | rect.y += yOffset; 23 | rect.height = EditorGUI.GetPropertyHeight(childrenProperty); 24 | EditorGUI.PropertyField(rect, childrenProperty); 25 | 26 | yOffset += rect.height + EditorGUIUtility.standardVerticalSpacing; 27 | } 28 | 29 | EditorGUI.EndDisabledGroup(); 30 | EditorGUI.EndProperty(); 31 | } 32 | 33 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 34 | { 35 | var childrenProperties = PropertiesUtils.GetSerializedProperties(property); 36 | 37 | var height = 0f; 38 | foreach (var childrenProperty in childrenProperties) 39 | { 40 | height += EditorGUI.GetPropertyHeight(childrenProperty); 41 | height += EditorGUIUtility.standardVerticalSpacing; 42 | } 43 | 44 | return height; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Editor/BuildPreprocessors/WebGLTemplateSelector/WebglTemplatePreprocessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using UnityEditor; 4 | using UnityEditor.Build.Reporting; 5 | using UnityEngine; 6 | 7 | namespace Deploy.Editor.BuildPreprocessors.WebGLTemplateSelector 8 | { 9 | [Serializable] 10 | public class WebglTemplatePreprocessor : OnDemandBuildPreprocessorWithReport 11 | { 12 | public const string TemplateResourcePath = "WebGLTemplateSelector"; 13 | 14 | [SerializeField] private SerializableWebGLTemplate _templateSelector; 15 | 16 | protected override void OnPreprocessBuildInternal(BuildReport report) 17 | { 18 | if (report.summary.platform == BuildTarget.WebGL) 19 | { 20 | var templateSelector = Resources.Load(TemplateResourcePath); 21 | PlayerSettings.WebGL.template = templateSelector.Template; 22 | } 23 | } 24 | 25 | public override void OnValidate() 26 | { 27 | EnsureDataExists(); 28 | } 29 | 30 | private void EnsureDataExists() 31 | { 32 | if (_templateSelector == null) 33 | { 34 | _templateSelector = Resources.Load(TemplateResourcePath); 35 | } 36 | 37 | if (_templateSelector == null) 38 | { 39 | _templateSelector = ScriptableObject.CreateInstance(); 40 | var assetPath = $"Assets/Editor/Resources/{TemplateResourcePath}.asset"; 41 | var assetDir = Path.GetDirectoryName(assetPath); 42 | if (!Directory.Exists(assetDir)) 43 | { 44 | Directory.CreateDirectory(assetDir); 45 | } 46 | 47 | AssetDatabase.CreateAsset(_templateSelector, assetPath); 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /.github/actions/deploy/telegram/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Deploy to Telegram' 2 | description: 'Sends a file to Telegram' 3 | inputs: 4 | buildPath: 5 | required: true 6 | default: '' 7 | description: 'File path' 8 | message: 9 | required: false 10 | default: "" 11 | description: "Caption message to send along the file" 12 | TELEGRAM_SESSION: 13 | required: true 14 | TELEGRAM_API_ID: 15 | required: true 16 | TELEGRAM_API_HASH: 17 | required: true 18 | TELEGRAM_TOKEN: 19 | required: true 20 | TELEGRAM_CHAT_ID: 21 | required: true 22 | 23 | runs: 24 | using: "composite" 25 | steps: 26 | - name: Check if file size is greater than 50 MB 27 | id: sizecheck 28 | shell: bash 29 | run: | 30 | maxsize=50000000 31 | filesize=$(stat -c%s "${{ inputs.buildPath }}") 32 | echo "The build size is $filesize bytes." 33 | if (( filesize > maxsize )); then 34 | echo "::set-output name=bigger::true" 35 | else 36 | echo "::set-output name=bigger::false" 37 | fi 38 | - name: Send file to telegram 39 | if: ${{ steps.sizecheck.outputs.bigger == 'false' }} 40 | uses: appleboy/telegram-action@master 41 | with: 42 | to: ${{ inputs.TELEGRAM_CHAT_ID }} 43 | token: ${{ inputs.TELEGRAM_TOKEN }} 44 | message: ${{ inputs.message }} 45 | document: ${{ inputs.buildPath }} 46 | - name: Send file to telegram with MTProto API 47 | if: ${{ steps.sizecheck.outputs.bigger == 'true' }} 48 | uses: mnicolas94/telegram-file-uploader@main 49 | with: 50 | session-name: ${{ inputs.TELEGRAM_SESSION }} 51 | api-id: ${{ inputs.TELEGRAM_API_ID }} 52 | api-hash: ${{ inputs.TELEGRAM_API_HASH }} 53 | bot-token: ${{ inputs.TELEGRAM_TOKEN }} 54 | chat-id: ${{ inputs.TELEGRAM_CHAT_ID }} 55 | file-path: ${{ inputs.buildPath }} 56 | message: ${{ inputs.message }} 57 | reply-request: 'The file size is bigger than 50 MB. Please, reply to this message to give me permission to send you the file' 58 | -------------------------------------------------------------------------------- /Editor/Utility/DeployContextsListPopulator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using Deploy.Editor.Data; 6 | using Deploy.Editor.VisualElements; 7 | using UnityEditor; 8 | using UnityEngine; 9 | using UnityEngine.UIElements; 10 | using Object = UnityEngine.Object; 11 | 12 | namespace Deploy.Editor.Utility 13 | { 14 | public static class DeployContextsListPopulator 15 | { 16 | public static void LoadContexts(List contexts) 17 | { 18 | contexts.Clear(); 19 | AssetDatabase.Refresh(); 20 | var loadedContexts = AssetDatabase.FindAssets("t:DeployContext") 21 | .Select(AssetDatabase.GUIDToAssetPath) 22 | .Select(AssetDatabase.LoadAssetAtPath) 23 | .ToList(); 24 | contexts.AddRange(loadedContexts); 25 | } 26 | 27 | public static void FillListView(ListView listView, List contexts, Action onBind) 28 | { 29 | listView.makeItem = () => new RenamableLabel(""); 30 | listView.bindItem = (item, index) => 31 | { 32 | var context = contexts[index]; 33 | item.userData = context; 34 | if (item is RenamableLabel renamableLabel) 35 | { 36 | renamableLabel.Text = context.name; 37 | renamableLabel.OnRename += (newText) => RenameItemData(newText, renamableLabel); 38 | } 39 | 40 | onBind.Invoke(item); 41 | }; 42 | listView.itemsSource = contexts; 43 | } 44 | 45 | private static void RenameItemData(string newName, RenamableLabel renamableLabel) 46 | { 47 | var context = renamableLabel.userData as DeployContext; 48 | Undo.RecordObject(context, "Change DeployContext name"); 49 | var path = AssetDatabase.GetAssetPath(context); 50 | AssetDatabase.RenameAsset(path, newName); 51 | EditorUtility.SetDirty(context); 52 | AssetDatabase.SaveAssets(); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /.github/actions/free-disk-space/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Free disk space' 2 | description: 'Free disk space' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Free space before build 8 | shell: bash 9 | run: | 10 | echo "==============================================================================" 11 | echo "Freeing up disk space on CI system" 12 | echo "==============================================================================" 13 | 14 | # echo "Listing 100 largest packages" 15 | # dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n | tail -n 100 16 | 17 | echo "==================" 18 | echo "Disk space at the beginning:" 19 | df -h 20 | 21 | sudo apt-get remove -qq -y '^ghc-8.*' || true 22 | sudo apt-get remove -qq -y '^dotnet-.*' || true 23 | sudo apt-get remove -qq -y '^llvm-.*' || true 24 | sudo apt-get remove -qq -y 'php.*' || true 25 | sudo apt-get remove -y azure-cli google-cloud-sdk google-chrome-stable firefox powershell mono-devel || true 26 | sudo apt-get autoremove -y 27 | sudo apt clean 28 | 29 | echo "Disk space after sudo apt-get removes:" 30 | df -h 31 | echo "------------------" 32 | echo "" 33 | 34 | echo "Removing large directories" 35 | # https://github.com/apache/flink/blob/master/tools/azure-pipelines/free_disk_space.sh 36 | rm -rf /usr/share/dotnet/ 37 | 38 | echo "Disk space after rm -rf /usr/share/dotnet/:" 39 | df -h 40 | echo "------------------" 41 | echo "" 42 | 43 | # https://github.com/actions/virtual-environments/issues/709#issuecomment-612569242 44 | rm -rf "/usr/local/share/boost" 45 | 46 | echo "Disk space after rm -rf "/usr/local/share/boost":" 47 | df -h 48 | echo "------------------" 49 | echo "" 50 | 51 | # Discarded 52 | #sudo swapoff -a 53 | #sudo rm -f /swapfile 54 | #rm -rf "$AGENT_TOOLSDIRECTORY" This can break Python 55 | #docker rmi $(docker images -q) # removing docker images breaks appleboy/telegram-action action. 56 | -------------------------------------------------------------------------------- /Editor/Utility/TabBarUtility.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine.UIElements; 3 | using Toggle = UnityEngine.UIElements.Toggle; 4 | 5 | namespace Deploy.Editor.Utility 6 | { 7 | public static class TabBarUtility 8 | { 9 | public static void SetupTabBar(List<(Toggle, VisualElement)> buttonsAndContainers) 10 | { 11 | var toggleGroup = buttonsAndContainers.ConvertAll(tuple => tuple.Item1); 12 | var containers = buttonsAndContainers.ConvertAll(tuple => tuple.Item2); 13 | 14 | buttonsAndContainers.ForEach(tuple => 15 | { 16 | var (toggle, container) = tuple; 17 | 18 | toggle.RegisterCallback(evt => 19 | { 20 | if (toggle.value) 21 | { 22 | EnableTab(toggle, container, toggleGroup, containers); 23 | } 24 | else 25 | { 26 | toggle.value = true; 27 | } 28 | }); 29 | }); 30 | 31 | // enable the first tab 32 | var (firstToggle, firstContainer) = buttonsAndContainers[0]; 33 | EnableTab(firstToggle, firstContainer, toggleGroup, containers); 34 | firstToggle.value = true; 35 | } 36 | 37 | private static void EnableTab( 38 | Toggle toggle, VisualElement container, List toggleGroup, List containers) 39 | { 40 | DisableGroup(toggle, toggleGroup); 41 | DisableAllContainers(containers); 42 | container.style.display = DisplayStyle.Flex; 43 | } 44 | 45 | private static void DisableGroup(Toggle except, List toggleGroup) 46 | { 47 | toggleGroup.ForEach(toggle => 48 | { 49 | if (toggle != except) 50 | { 51 | toggle.value = false; 52 | } 53 | }); 54 | } 55 | 56 | private static void DisableAllContainers(List containers) 57 | { 58 | containers.ForEach(container => container.style.display = DisplayStyle.None); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Editor/Drawers/PlayStorePropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using Deploy.Editor.DeployPlatforms; 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace Deploy.Editor.Drawers 6 | { 7 | [CustomPropertyDrawer(typeof(PlayStore))] 8 | public class PlayStorePropertyDrawer : PropertyDrawer 9 | { 10 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 11 | { 12 | return EditorGUI.GetPropertyHeight(property, label); 13 | } 14 | 15 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 16 | { 17 | var foldoutRect = new Rect(position); 18 | foldoutRect.height = EditorGUIUtility.singleLineHeight; 19 | property.isExpanded = EditorGUI.Foldout( 20 | foldoutRect, 21 | property.isExpanded, 22 | label); 23 | 24 | var indent = EditorGUI.indentLevel; 25 | EditorGUI.indentLevel++; 26 | if (property.isExpanded) 27 | { 28 | float yOffset = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; 29 | var iterator = property; 30 | var parentPath = iterator.propertyPath; 31 | bool isChild = true; 32 | bool nextVisible = true; 33 | while (iterator.NextVisible(nextVisible) && isChild) 34 | { 35 | nextVisible = false; 36 | isChild = iterator.propertyPath.StartsWith(parentPath); 37 | if (iterator.name == "m_Script" || !isChild) 38 | { 39 | continue; 40 | } 41 | 42 | var labelString = ObjectNames.NicifyVariableName(iterator.name); 43 | var height = EditorGUI.GetPropertyHeight(iterator); 44 | var rects = new Rect(position.x, position.y + yOffset, position.width, height); 45 | yOffset += height + EditorGUIUtility.standardVerticalSpacing; 46 | 47 | EditorGUI.PropertyField(rects, iterator, new GUIContent(labelString), true); 48 | } 49 | } 50 | EditorGUI.indentLevel = indent; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Tests/Editor/OverrideVariablesTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Deploy.Editor.Data; 4 | using NUnit.Framework; 5 | using UnityEditor; 6 | using UnityEditor.Presets; 7 | 8 | namespace Deploy.Tests.Editor 9 | { 10 | public class OverrideVariablesTests 11 | { 12 | private static List> _overrides = new () 13 | { 14 | () => new BuildVariableValue( 15 | TestScriptableObject.Get(1, 2, "qwe"), 16 | TestScriptableObject.Get(4, 5, "asd")), 17 | () => new BuildVariableValue( 18 | TestScriptableObject.Get(1, 2, "qwe"), 19 | new Preset(TestScriptableObject.Get(4, 5, "asd"))), 20 | }; 21 | 22 | [TestCaseSource(nameof(_overrides))] 23 | public void When_ApplyOverrideWithBuildVariableValue_OverridesAreAppliedCorrectly(Func factory) 24 | { 25 | // arrange 26 | // create asset file for it to have guid 27 | var overrideVariable = factory(); 28 | var assetPath = "Assets/Deploy/Tests/Editor/test.asset"; 29 | AssetDatabase.CreateAsset(overrideVariable.Variable, assetPath); 30 | AssetDatabase.Refresh(); 31 | 32 | var variables = new List() 33 | { 34 | overrideVariable 35 | }; 36 | 37 | // false-positive assert 38 | var variable = overrideVariable.Variable as TestScriptableObject; 39 | var overrideValue = overrideVariable.OverrideVariable as TestScriptableObject; 40 | Assert.IsFalse(variable.IsEqualTo(overrideValue)); 41 | 42 | // act 43 | var base64 = variables.OverrideVariablesToBase64(); 44 | OverrideVariablesListExtensions.ApplyOverrideVariablesValues(base64); 45 | 46 | // assert 47 | variable = overrideVariable.Variable as TestScriptableObject; 48 | overrideValue = overrideVariable.OverrideVariable as TestScriptableObject; 49 | Assert.IsTrue(variable.IsEqualTo(overrideValue)); 50 | 51 | // teardown 52 | AssetDatabase.DeleteAsset(assetPath); 53 | AssetDatabase.Refresh(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Editor/EditorWindows/Resources/DeployEditorWindow.uxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Editor/Resources/workflow_template.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | base64_json: 7 | type: string 8 | required: true 9 | 10 | jobs: 11 | decode_input: 12 | name: Parse base64 input 13 | runs-on: ubuntu-latest 14 | outputs: 15 | input: ${{ steps.decode.outputs.input }} 16 | steps: 17 | - name: Decode input 18 | id: decode 19 | run: | 20 | input=$(echo "${{ inputs.base64_json }}" | base64 --decode) 21 | echo "$input" 22 | echo "input<<_EOF_" >> $GITHUB_OUTPUT 23 | echo "$input" >> $GITHUB_OUTPUT 24 | echo "_EOF_" >> $GITHUB_OUTPUT 25 | 26 | build_and_deploy: 27 | needs: [ decode_input ] 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | include: ${{ fromJson(needs.decode_input.outputs.input) }} 32 | uses: mnicolas94/facticus-deploy/.github/workflows/workflow_call.yml@v0.6.36 33 | with: 34 | json_input: ${{ toJson(matrix) }} 35 | secrets: 36 | UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} 37 | UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} 38 | UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} 39 | ANDROID_KEYSTORE_NAME: ${{ secrets.ANDROID_KEYSTORE_NAME }} 40 | ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} 41 | ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }} 42 | ANDROID_KEYALIAS_NAME: ${{ secrets.ANDROID_KEYALIAS_NAME }} 43 | ANDROID_KEYALIAS_PASS: ${{ secrets.ANDROID_KEYALIAS_PASS }} 44 | DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }} 45 | DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} 46 | ITCH_BUTLER_CREDENTIALS: ${{ secrets.ITCH_BUTLER_CREDENTIALS }} 47 | ITCH_GAME: ${{ secrets.ITCH_GAME }} 48 | ITCH_USER: ${{ secrets.ITCH_USER }} 49 | TELEGRAM_SESSION: ${{ secrets.TELEGRAM_SESSION }} 50 | TELEGRAM_API_ID: ${{ secrets.TELEGRAM_API_ID }} 51 | TELEGRAM_API_HASH: ${{ secrets.TELEGRAM_API_HASH }} 52 | TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} 53 | TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} 54 | PLAY_STORE_SERVICE_ACCOUNT_JSON: ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT_JSON }} 55 | PLAY_STORE_PACKAGE_NAME: ${{ secrets.PLAY_STORE_PACKAGE_NAME }} 56 | STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} 57 | STEAM_CONFIG_VDF: ${{ secrets.STEAM_CONFIG_VDF }} 58 | STEAM_APP_ID: ${{ secrets.STEAM_APP_ID }} -------------------------------------------------------------------------------- /Editor/Utility/TerminalUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace Deploy.Editor.Utility 5 | { 6 | public static class TerminalUtils 7 | { 8 | public static (string, string) RunCommand(string command, string options, string workingDir, 9 | bool createAsCmdPopup = false) 10 | { 11 | if (createAsCmdPopup) 12 | { 13 | #if UNITY_EDITOR_WIN 14 | options = $"/k {command} {options}"; 15 | command = "cmd.exe"; 16 | #else 17 | options = $"-c '{command} {options}'"; 18 | command = "bash"; 19 | #endif 20 | } 21 | 22 | // Set up our processInfo to run the command and log to output and errorOutput. 23 | ProcessStartInfo processInfo = new ProcessStartInfo(command, options) 24 | { 25 | WorkingDirectory = workingDir, 26 | CreateNoWindow = !createAsCmdPopup, // We want no visible pop-ups 27 | UseShellExecute = createAsCmdPopup, // Allows us to redirect input, output and error streams 28 | RedirectStandardOutput = !createAsCmdPopup, // Allows us to read the output stream 29 | RedirectStandardError = !createAsCmdPopup // Allows us to read the error stream 30 | }; 31 | 32 | // Set up the Process 33 | Process process = new Process 34 | { 35 | StartInfo = processInfo 36 | }; 37 | process.Start(); 38 | 39 | if (createAsCmdPopup) 40 | { 41 | return ("", ""); 42 | } 43 | 44 | // Read the results back from the process so we can get the output and check for errors 45 | var output = process.StandardOutput.ReadToEnd(); 46 | var errorOutput = process.StandardError.ReadToEnd(); 47 | 48 | process.WaitForExit(); // Make sure we wait till the process has fully finished. 49 | int exitCode = process.ExitCode; 50 | bool hadErrors = process.ExitCode != 0; 51 | process.Close(); // Close the process ensuring it frees it resources. 52 | 53 | if (hadErrors) 54 | { 55 | throw new Exception($"{output}\n{errorOutput}"); 56 | } 57 | 58 | return (output, errorOutput); 59 | } 60 | 61 | public static string RunCommandMergeOutputs(string command, string options, string workingDir, bool createAsCmdPopup=false) 62 | { 63 | var (output, errorOutput) = RunCommand(command, options, workingDir, createAsCmdPopup); 64 | 65 | return $"Output:\n{output}\n\nErrorOutput:\n{errorOutput}"; // Return the output 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Editor/VisualElements/RenamableLabel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.UIElements; 4 | 5 | namespace Deploy.Editor.VisualElements 6 | { 7 | public class RenamableLabel : VisualElement 8 | { 9 | public Action OnRename; 10 | 11 | protected Label _label; 12 | protected TextField _renameField; 13 | 14 | public string Text { 15 | get => _label.text; 16 | set { 17 | if (string.IsNullOrEmpty(value) || value.Equals("(Unnamed)")) 18 | { 19 | _label.text = "(Unnamed)"; 20 | _label.style.unityFontStyleAndWeight = FontStyle.Italic; 21 | } 22 | else 23 | { 24 | _label.text = value; 25 | _label.style.unityFontStyleAndWeight = FontStyle.Normal; 26 | } 27 | } 28 | } 29 | 30 | public RenamableLabel(string text) 31 | { 32 | RegisterCallback(MouseRename, TrickleDown.TrickleDown); 33 | 34 | focusable = true; 35 | pickingMode = PickingMode.Position; 36 | RegisterCallback(KeyboardShortcuts, TrickleDown.TrickleDown); 37 | 38 | _label = new Label(text); 39 | Insert(0, _label); 40 | 41 | _renameField = new TextField { name = "textField", isDelayed = true }; 42 | _renameField.style.display = DisplayStyle.None; 43 | _renameField.ElementAt(0).style.fontSize = _label.style.fontSize; 44 | _renameField.ElementAt(0).style.height = 18f; 45 | // _renameField.style.paddingTop = 8.5f; 46 | // _renameField.style.paddingLeft = 4f; 47 | // _renameField.style.paddingRight = 4f; 48 | // _renameField.style.paddingBottom = 7.5f; 49 | Insert(1, _renameField); 50 | 51 | VisualElement textInput = _renameField.Q(TextField.textInputUssName); 52 | textInput.RegisterCallback(EndRename); 53 | } 54 | 55 | private void MouseRename(MouseDownEvent evt) 56 | { 57 | if (evt.clickCount == 2 && evt.button == (int)MouseButton.LeftMouse) 58 | { 59 | StartRename(); 60 | } 61 | } 62 | 63 | private void KeyboardShortcuts(KeyDownEvent evt) 64 | { 65 | if (evt.keyCode == KeyCode.F2) 66 | { 67 | StartRename(); 68 | } 69 | } 70 | 71 | public void StartRename() 72 | { 73 | _label.style.display = DisplayStyle.None; 74 | _renameField.SetValueWithoutNotify(Text); 75 | _renameField.style.display = DisplayStyle.Flex; 76 | _renameField.Q(TextField.textInputUssName).Focus(); 77 | _renameField.SelectAll(); 78 | } 79 | 80 | private void EndRename(FocusOutEvent evt) 81 | { 82 | _label.style.display = DisplayStyle.Flex; 83 | _renameField.style.display = DisplayStyle.None; 84 | 85 | if (Text != _renameField.text) 86 | { 87 | Text = _renameField.text; 88 | OnRename?.Invoke(Text); 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /Editor/Settings/DeploySettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.IO; 5 | using Deploy.Editor.BackEnds; 6 | using Deploy.Editor.BuildPreprocessors; 7 | using Deploy.Editor.NotifyPlatforms; 8 | using Deploy.Editor.Versioning; 9 | using UnityEditor; 10 | using UnityEngine; 11 | using Utils.Editor; 12 | 13 | namespace Deploy.Editor.Settings 14 | { 15 | public class DeploySettings : ScriptableObjectSingleton 16 | { 17 | public static string PropertyNameWorkflowId => nameof(_workflowId); 18 | public static string PropertyNameOnDemandBuildPreprocessors => nameof(_onDemandBuildPreprocessors); 19 | 20 | [SerializeField] private string _workflowId; 21 | public string WorkflowId 22 | { 23 | get => _workflowId; 24 | set => _workflowId = value; 25 | } 26 | 27 | [SerializeField, Tooltip("Update the workflow file automatically on package update. It will update the version " + 28 | "of actions used to build and deploy your project. Remember to commit and push the changes" + 29 | " to the workflow file before clicking 'Build and Deploy'")] 30 | private bool _updateWorkflowAutomatically; 31 | public bool UpdateWorkflowAutomatically => _updateWorkflowAutomatically; 32 | 33 | [SerializeField] private string _gitDirectory; 34 | public string GitDirectory => _gitDirectory; 35 | 36 | [SerializeField] private string _defaultAssetDirectory = "Assets/Editor/Deploy"; 37 | public string DefaultAssetDirectory => 38 | string.IsNullOrEmpty(_defaultAssetDirectory) ? "Assets": _defaultAssetDirectory; 39 | 40 | [SerializeReference, SubclassSelector] private ICicdBackend _backend; 41 | public ICicdBackend Backend => _backend; 42 | 43 | [SerializeReference, SubclassSelector] private INotifyPlatform _notifyPlatform; 44 | public INotifyPlatform NotifyPlatform => _notifyPlatform; 45 | 46 | [SerializeField] private VersioningStrategy _versioningStrategy; 47 | public VersioningStrategy VersioningStrategy => _versioningStrategy; 48 | 49 | [SerializeReference, SubclassSelector] 50 | [Tooltip("This is a list of build preprocessors that will only trigger if they are added to this list")] 51 | private List _onDemandBuildPreprocessors = new(); 52 | public ReadOnlyCollection OnDemandBuildPreprocessors => _onDemandBuildPreprocessors.AsReadOnly(); 53 | 54 | public static DeploySettings GetOrCreate() 55 | { 56 | if (Instance == null) 57 | { 58 | // create directory 59 | var dir = "Assets/Editor/Deploy"; 60 | Directory.CreateDirectory(dir); 61 | AssetDatabase.Refresh(); 62 | 63 | // create asset 64 | var settings = CreateInstance(); 65 | var path = Path.Combine(dir, "DeploySettings.asset"); 66 | AssetDatabase.CreateAsset(settings, path); 67 | AssetDatabase.SaveAssets(); 68 | } 69 | 70 | return Instance; 71 | } 72 | 73 | private void OnValidate() 74 | { 75 | if (_backend == null) 76 | { 77 | _backend = new GithubActionsBackend(); 78 | } 79 | 80 | foreach (var processor in _onDemandBuildPreprocessors) 81 | { 82 | processor?.OnValidate(); 83 | } 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Editor/DeployPlatforms/IDeployPlatform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Deploy.Editor.Utility; 5 | using UnityEngine; 6 | using Utils.Attributes; 7 | 8 | namespace Deploy.Editor.DeployPlatforms 9 | { 10 | public interface IDeployPlatform 11 | { 12 | string GetPlatformName(); 13 | string GetFieldsPrefix(); 14 | } 15 | 16 | [Serializable] 17 | public class Telegram : IDeployPlatform 18 | { 19 | public string GetPlatformName() => "Telegram"; 20 | public string GetFieldsPrefix() => "telegram"; 21 | 22 | [SerializeField] private string message; 23 | 24 | public string Message 25 | { 26 | get => message; 27 | set => message = value; 28 | } 29 | } 30 | 31 | [Serializable] 32 | public class Steam : IDeployPlatform 33 | { 34 | public string GetPlatformName() => "Steam"; 35 | public string GetFieldsPrefix() => "steam"; 36 | 37 | [SerializeField] private string releaseBranch; 38 | } 39 | 40 | [Serializable] 41 | public class Itch : IDeployPlatform 42 | { 43 | public string GetPlatformName() => "Itch"; 44 | public string GetFieldsPrefix() => "itch"; 45 | 46 | [SerializeField] private string channel; 47 | } 48 | 49 | [Serializable] 50 | public class GithubRelease : IDeployPlatform 51 | { 52 | public string GetPlatformName() => "GithubRelease"; 53 | public string GetFieldsPrefix() => "ghR"; 54 | } 55 | 56 | [Serializable] 57 | public class PlayStore : IDeployPlatform, IJsonSerializable 58 | { 59 | public string GetPlatformName() => "PlayStore"; 60 | public string GetFieldsPrefix() => "playstore"; 61 | 62 | [SerializeField, Dropdown(nameof(GetTrackValues))] 63 | private string track; 64 | [SerializeField, Dropdown(nameof(GetStatusValues))] 65 | private string status; 66 | [SerializeField, Range(0, 5)] private int inAppUpdatePriority; 67 | [SerializeField, Range(0.0001f, 0.9999f)] private float userFraction = 0.5f; 68 | 69 | public string ToJson() 70 | { 71 | var dict = new Dictionary 72 | { 73 | {"track", $"\"{track}\""}, 74 | {"status", $"\"{status}\""}, 75 | {"inAppUpdatePriority", inAppUpdatePriority.ToString()}, 76 | {"userFraction", userFraction.ToString()}, 77 | }; 78 | 79 | if (status is not "inProgress" and not "halted" ) 80 | { 81 | dict.Remove("userFraction"); 82 | } 83 | 84 | var json = DictToJson(dict); 85 | return json; 86 | } 87 | 88 | private string DictToJson(Dictionary dict) 89 | { 90 | var keyValuesEnumerable = dict.Select(d => $"\"{d.Key}\":{d.Value}"); 91 | var keyValues = string.Join(",", keyValuesEnumerable); 92 | return $"{{{keyValues}}}"; 93 | } 94 | 95 | private List GetTrackValues() 96 | { 97 | return new List 98 | { 99 | "production", 100 | "beta", 101 | "alpha", 102 | "internalsharing", 103 | "internal", 104 | }; 105 | } 106 | 107 | private List GetStatusValues() 108 | { 109 | return new List 110 | { 111 | "completed", 112 | "inProgress", 113 | "halted", 114 | "draft", 115 | }; 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /Editor/Settings/WorkflowVersionUpdater.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text.RegularExpressions; 3 | using UnityEditor; 4 | using UnityEditor.PackageManager.UI; 5 | using UnityEngine; 6 | using UnityEngine.UIElements; 7 | using PackageInfo = UnityEditor.PackageManager.PackageInfo; 8 | 9 | namespace Deploy.Editor.Settings 10 | { 11 | [InitializeOnLoad] 12 | public class WorkflowVersionUpdater : IPackageManagerExtension 13 | { 14 | static WorkflowVersionUpdater() 15 | { 16 | PackageManagerExtensions.RegisterExtension(new WorkflowVersionUpdater()); 17 | } 18 | 19 | public VisualElement CreateExtensionUI() 20 | { 21 | return null; 22 | } 23 | 24 | public void OnPackageSelectionChange(PackageInfo packageInfo) 25 | { 26 | } 27 | 28 | public void OnPackageAddedOrUpdated(PackageInfo packageInfo) 29 | { 30 | if (IsSelf(packageInfo)) 31 | { 32 | if (DeploySettings.GetOrCreate().UpdateWorkflowAutomatically) 33 | { 34 | var revision = packageInfo.git.revision; 35 | var isMainRev = revision is "main" or "HEAD"; 36 | var newVersion = isMainRev ? $"v{packageInfo.version}" : revision; 37 | SetWorkflowVersion(newVersion); 38 | } 39 | } 40 | } 41 | 42 | public void OnPackageRemoved(PackageInfo packageInfo) 43 | { 44 | } 45 | 46 | private bool IsSelf(PackageInfo packageInfo) 47 | { 48 | return packageInfo.name == "com.facticus.deploy"; 49 | } 50 | 51 | private static string GetWorkflowPath() 52 | { 53 | var deploySettings = DeploySettings.GetOrCreate(); 54 | var filename = deploySettings.WorkflowId; 55 | var path = Path.Combine(deploySettings.GitDirectory, ".github", "workflows", $"{filename}.yml"); 56 | return path; 57 | } 58 | 59 | private static string GetWorkflowVersion() 60 | { 61 | var path = GetWorkflowPath(); 62 | 63 | var groupName = "ver"; 64 | var rxPattern = new Regex($"uses: mnicolas94/facticus-deploy/.github/.*/.*@(?<{groupName}>.*)"); 65 | 66 | var lines = File.ReadAllLines(path); 67 | foreach (var line in lines) 68 | { 69 | var matches = rxPattern.Matches(line); 70 | foreach (Match match in matches) 71 | { 72 | var ver = match.Groups[groupName]; 73 | return ver.Value; 74 | } 75 | } 76 | 77 | return "NO-VERSION"; 78 | } 79 | 80 | private static void SetWorkflowVersion(string newVersion) 81 | { 82 | var path = GetWorkflowPath(); 83 | 84 | var groupName = "ver"; 85 | var pattern = $"(uses: mnicolas94/facticus-deploy/.github/.*/.*@)(?<{groupName}>.*)"; 86 | var regex = new Regex(pattern); 87 | 88 | var lines = File.ReadAllLines(path); 89 | var newLines = new string[lines.Length]; 90 | for (int i = 0; i < lines.Length; i++) 91 | { 92 | var line = lines[i]; 93 | var matches = regex.Matches(line); 94 | foreach (Match match in matches) 95 | { 96 | line = Regex.Replace(line, pattern, $"$1{newVersion}"); 97 | } 98 | 99 | newLines[i] = line; 100 | } 101 | 102 | var allText = string.Join("\n", newLines); 103 | File.WriteAllText(path, allText); 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /.github/workflows/workflow_call_json_file.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy with json file as input 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | json_file: 7 | type: string 8 | required: true 9 | secrets: 10 | # Build secrets 11 | UNITY_LICENSE: 12 | required: true 13 | UNITY_EMAIL: 14 | required: true 15 | UNITY_PASSWORD: 16 | required: true 17 | # Build for Android 18 | ANDROID_KEYSTORE_NAME: 19 | required: false 20 | ANDROID_KEYSTORE_BASE64: 21 | required: false 22 | ANDROID_KEYSTORE_PASS: 23 | required: false 24 | ANDROID_KEYALIAS_NAME: 25 | required: false 26 | ANDROID_KEYALIAS_PASS: 27 | required: false 28 | # Discord 29 | DISCORD_WEBHOOK_ID: 30 | required: false 31 | DISCORD_WEBHOOK_TOKEN: 32 | required: false 33 | # Itch.io 34 | ITCH_BUTLER_CREDENTIALS: 35 | required: false 36 | ITCH_GAME: 37 | required: false 38 | ITCH_USER: 39 | required: false 40 | # Telegram 41 | TELEGRAM_SESSION: 42 | required: false 43 | TELEGRAM_API_ID: 44 | required: false 45 | TELEGRAM_API_HASH: 46 | required: false 47 | TELEGRAM_TOKEN: 48 | required: false 49 | TELEGRAM_CHAT_ID: 50 | required: false 51 | # Play Store 52 | PLAY_STORE_SERVICE_ACCOUNT_JSON: 53 | required: false 54 | PLAY_STORE_PACKAGE_NAME: 55 | required: false 56 | # Steam 57 | STEAM_USERNAME: 58 | required: false 59 | STEAM_CONFIG_VDF: 60 | required: false 61 | STEAM_APP_ID: 62 | required: false 63 | 64 | jobs: 65 | read_input: 66 | name: Read json input for Deploy 67 | runs-on: ubuntu-latest 68 | outputs: 69 | input: ${{ steps.read.outputs.input }} 70 | steps: 71 | - uses: actions/checkout@v4 72 | with: 73 | fetch-depth: 0 74 | 75 | - name: Read input from json file 76 | id: read 77 | run: | 78 | file=${{ github.workspace }}/.github/workflows/${{ inputs.json_file }} 79 | input=$(cat $file) 80 | echo "$input" 81 | echo "input<<_EOF_" >> $GITHUB_OUTPUT 82 | echo "$input" >> $GITHUB_OUTPUT 83 | echo "_EOF_" >> $GITHUB_OUTPUT 84 | 85 | build_deploy: 86 | uses: mnicolas94/facticus-deploy/.github/workflows/workflow_call.yml@v0.6.36 87 | needs: [ read_input ] 88 | strategy: 89 | fail-fast: false 90 | matrix: 91 | include: ${{ fromJson(needs.read_input.outputs.input) }} 92 | with: 93 | json_input: ${{ toJson(matrix) }} 94 | secrets: 95 | UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} 96 | UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} 97 | UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} 98 | ANDROID_KEYSTORE_NAME: ${{ secrets.ANDROID_KEYSTORE_NAME }} 99 | ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} 100 | ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }} 101 | ANDROID_KEYALIAS_NAME: ${{ secrets.ANDROID_KEYALIAS_NAME }} 102 | ANDROID_KEYALIAS_PASS: ${{ secrets.ANDROID_KEYALIAS_PASS }} 103 | DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }} 104 | DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} 105 | ITCH_BUTLER_CREDENTIALS: ${{ secrets.ITCH_BUTLER_CREDENTIALS }} 106 | ITCH_GAME: ${{ secrets.ITCH_GAME }} 107 | ITCH_USER: ${{ secrets.ITCH_USER }} 108 | TELEGRAM_SESSION: ${{ secrets.TELEGRAM_SESSION }} 109 | TELEGRAM_API_ID: ${{ secrets.TELEGRAM_API_ID }} 110 | TELEGRAM_API_HASH: ${{ secrets.TELEGRAM_API_HASH }} 111 | TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }} 112 | TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} 113 | PLAY_STORE_SERVICE_ACCOUNT_JSON: ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT_JSON }} 114 | PLAY_STORE_PACKAGE_NAME: ${{ secrets.PLAY_STORE_PACKAGE_NAME }} 115 | STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} 116 | STEAM_CONFIG_VDF: ${{ secrets.STEAM_CONFIG_VDF }} 117 | STEAM_APP_ID: ${{ secrets.STEAM_APP_ID }} 118 | -------------------------------------------------------------------------------- /.github/actions/deploy/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Deploy' 2 | description: 'Sends a file to deploy' 3 | inputs: 4 | deployPlatform: 5 | required: true 6 | description: 'Platform to deploy' 7 | buildPath: 8 | required: true 9 | description: 'File to deploy' 10 | version: 11 | required: true 12 | description: 'build version' 13 | deployParameters: 14 | required: false 15 | default: '' 16 | description: 'Platform specific parameters in json format' 17 | 18 | runs: 19 | using: "composite" 20 | steps: 21 | # Telegram 22 | - name: Deploy to Telegram 23 | if: ${{ inputs.deployPlatform == 'Telegram'}} 24 | uses: mnicolas94/facticus-deploy/.github/actions/deploy/telegram@v0.6.36 25 | with: 26 | buildPath: ${{ inputs.buildPath }} 27 | message: ${{ fromJson(inputs.deployParameters).telegram_message }} 28 | TELEGRAM_SESSION: ${{ env.TELEGRAM_SESSION }} 29 | TELEGRAM_API_ID: ${{ env.TELEGRAM_API_ID }} 30 | TELEGRAM_API_HASH: ${{ env.TELEGRAM_API_HASH }} 31 | TELEGRAM_TOKEN: ${{ env.TELEGRAM_TOKEN }} 32 | TELEGRAM_CHAT_ID: ${{ env.TELEGRAM_CHAT_ID }} 33 | 34 | # Itchio 35 | - name: Deploy to Itch.io 36 | if: ${{ inputs.deployPlatform == 'Itch'}} 37 | uses: yeslayla/butler-publish-itchio-action@master 38 | env: 39 | BUTLER_CREDENTIALS: ${{ env.ITCH_BUTLER_CREDENTIALS }} 40 | CHANNEL: ${{ fromJson(inputs.deployParameters).itch_channel }} 41 | ITCH_GAME: ${{ env.ITCH_GAME }} 42 | ITCH_USER: ${{ env.ITCH_USER }} 43 | PACKAGE: ${{ inputs.buildPath }} 44 | VERSION: ${{ inputs.version }} 45 | 46 | # Steam 47 | - name: Deploy to Steam 48 | if: ${{ inputs.deployPlatform == 'Steam'}} 49 | uses: game-ci/steam-deploy@v3 50 | with: 51 | username: ${{ env.STEAM_USERNAME }} 52 | configVdf: ${{ env.STEAM_CONFIG_VDF }} 53 | appId: ${{ env.STEAM_APP_ID }} 54 | buildDescription: ${{ inputs.version }} 55 | rootPath: '' 56 | depot1Path: ${{ inputs.buildPath }} 57 | releaseBranch: ${{ fromJson(inputs.deployParameters).steam_releaseBranch }} 58 | 59 | # Play Store 60 | - name: Deploy to Play Store 61 | if: ${{ inputs.deployPlatform == 'PlayStore'}} 62 | uses: r0adkll/upload-google-play@v1 63 | with: 64 | serviceAccountJsonPlainText: ${{ env.PLAY_STORE_SERVICE_ACCOUNT_JSON }} 65 | packageName: ${{ env.PLAY_STORE_PACKAGE_NAME }} 66 | releaseFiles: ${{ inputs.buildPath }} 67 | # releaseName: ${{ inputs.version }} 68 | track: ${{ fromJson(inputs.deployParameters).playstore_track }} 69 | status: ${{ fromJson(inputs.deployParameters).playstore_status }} 70 | inAppUpdatePriority: ${{ fromJson(inputs.deployParameters).playstore_inAppUpdatePriority }} 71 | userFraction: ${{ fromJson(inputs.deployParameters).playstore_userFraction }} 72 | # whatsNewDirectory: ${{ inputs. }} 73 | # mappingFile: ${{ inputs. }} 74 | # debugSymbols: ${{ inputs. }} 75 | 76 | # Github Release 77 | - name: Checkout 78 | if: ${{ inputs.deployPlatform == 'GithubRelease'}} 79 | uses: actions/checkout@v4 80 | with: 81 | fetch-depth: 0 82 | - name: Create tag if it doesn't exist 83 | if: ${{ inputs.deployPlatform == 'GithubRelease'}} 84 | id: tag 85 | shell: bash 86 | run: | 87 | if [ $(git describe --tags --exact-match HEAD) ]; then 88 | echo "Current commit already has tag." 89 | echo "tag=$(git describe --tags --exact-match HEAD)" >> $GITHUB_OUTPUT 90 | else 91 | if [ -n $(git tag -l v${{ inputs.version }}) ]; then 92 | git tag v${{ inputs.version }} 93 | git push origin v${{ inputs.version }} 94 | fi 95 | echo "tag=v${{ inputs.version }}" >> $GITHUB_OUTPUT 96 | fi 97 | - name: Deploy to a Github release 98 | if: ${{ inputs.deployPlatform == 'GithubRelease'}} 99 | uses: softprops/action-gh-release@v1 100 | with: 101 | name: v${{ inputs.version }} 102 | tag_name: ${{ steps.tag.outputs.tag }} 103 | files: ${{ inputs.buildPath }} 104 | -------------------------------------------------------------------------------- /Editor/Drawers/BuildDeployElementDrawer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Deploy.Editor.Data; 4 | using UnityEditor; 5 | using UnityEditor.UIElements; 6 | using UnityEngine; 7 | using UnityEngine.UIElements; 8 | using Utils.Editor; 9 | 10 | namespace Deploy.Editor.Drawers 11 | { 12 | [CustomPropertyDrawer(typeof(BuildDeployElement))] 13 | public class BuildDeployElementDrawer : PropertyDrawer 14 | { 15 | public override VisualElement CreatePropertyGUI(SerializedProperty property) 16 | { 17 | return new BuildDeployElementField(property); 18 | } 19 | } 20 | 21 | public class BuildDeployElementField : VisualElement 22 | { 23 | private SerializedProperty _property; 24 | private Toggle _toggle; 25 | private Foldout _foldout; 26 | private Label _foldoutLabel; 27 | private VisualElement _propertiesContainer; 28 | 29 | private readonly string[] _propertiesToUpdateLabel = new[] 30 | { 31 | "_buildPlatform", 32 | "_deployPlatform" 33 | }; 34 | 35 | public BuildDeployElementField(SerializedProperty property) 36 | { 37 | _property = property; 38 | 39 | var labelString = GetLabel(property); 40 | 41 | // Enabled toggle 42 | var enabledProperty = property.FindPropertyRelative("_enabled"); 43 | _toggle = new Toggle(); 44 | _toggle.BindProperty(enabledProperty); 45 | _toggle.tooltip = enabledProperty.tooltip; 46 | _toggle.RegisterValueChangedCallback(OnEnabledChanged); 47 | _toggle.style.marginRight = 3; 48 | 49 | // Foldout 50 | _foldout = new Foldout(); 51 | _foldout.text = labelString; 52 | _foldout.style.marginLeft = 20; 53 | _foldout.RegisterValueChangedCallback(OnFoldoutChange); 54 | _foldoutLabel = _foldout.Q