diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..01de2e0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,227 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] + +# Change these settings to your own preference +indent_style = space +indent_size = 4 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +indent_style = tab +trim_trailing_whitespace = false + +[{manifest.json,package.json}] +indent_style = space +indent_size = 2 + +# Solution Files +[*.sln] +indent_style = tab + +# XML Project Files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# C# files +[*.cs] + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_property = false:silent + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# Expression-level preferences +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:suggestion + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_prefer_static_local_function = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = true:suggestion + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = inside_namespace:silent + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..e9eb538 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,28 @@ +# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests + +on: + workflow_dispatch: + schedule: + - cron: '40 20 * * *' + +jobs: + stale: + + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v4 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-label: 'stale' + stale-pr-label: 'stale' + exempt-issue-labels: 'bug,defect,enhancement,hacktoberfest,help wanted' + exempt-pr-labels: 'bug,defect,enhancement,hacktoberfest,help wanted' diff --git a/.gitignore b/.gitignore index 129e372..0b602e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,100 @@ -################ -# Sublime Text # -################ -*.sublime-project -*.sublime-workspace -###################### -# Visual Studio Code # -###################### -.vscode/ +# Created by https://www.toptal.com/developers/gitignore/api/sublimetext,vscode,windows,macos +# Edit at https://www.toptal.com/developers/gitignore?templates=sublimetext,vscode,windows,macos -########### -# OS Junk # -########### +### macOS ### +# General .DS_Store -.DS_Store? +.AppleDouble +.LSOverride + +# Icon must end with two \r +#Icon + + +# Thumbnails ._* -*.swp + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd .Spotlight-V100 +.TemporaryItems .Trashes -Icon? -ehthumbs.db +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### SublimeText ### +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +*.sublime-project + +# SFTP configuration file +sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +### vscode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +### Windows ### +# Windows thumbnail cache files Thumbs.db -$RECYCLE.BIN/ \ No newline at end of file +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/sublimetext,vscode,windows,macos diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fa1c40d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,128 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + +## [4.0.1] - 2023-10-10 + +### Fixed + +- Fixed output file name not being parsed for string tokens in `ZipFileOperation` action. (by [@cosformula](https://github.com/cosformula)) + +## [4.0.0] - 2023-10-03 + +### Added + +- Added support for new Per-Build and Single Run string tokens. Per-Build actions have gained support for `$BASEPATH` and `$BUILDPATH`, whilst Single Run actions can now use `$VERSION`, `$BUILD`, `$YEAR`, `$MONTH`, `$DAY` and `$TIME`, with the time-based tokens corresponding to the time at which the action was run. + +### Changed + +- Standardised string token usage across Build Actions. + +## [3.0.1] - 2023-05-23 + +### Fixed + +- Fixed minimum required SuperUnityBuild version. + +## [3.0.0] - 2023-05-16 + +### Added + +- **Breaking change:** Added support for new per-build scripting backend functionality. +- Added author details and documentation, changelog and license URLs to package manifest. + +### Changed + +- **Breaking change:** Drop support for versions of Unity older than 2020.3 LTS. +- Refactor `FileUtility` build action and fix exceptions when paths not configured. + +## [2.2.0] - 2022-02-03 + +### Added + +- Added support for WebGL and UWP platforms to `ItchUploader` action. + +### Fixed + +- Fixed `ItchUploader` action generating invalid butler command for unknown build platforms. + +## [2.1.1] - 2021-10-07 + +### Fixed + +- Fixed incorrect selection in audio spatializer dropdown on startup in `PerBuildAudioSettings` action. + +## [2.1.0] - 2021-08-24 + +### Added + +- Allow certain pre-build per-platform actions to optionally configure Editor. + +### Changed + +- Removed pre-Unity 2019.1 code. + +## [2.0.0] - 2021-05-13 + +### Changed + +- Increased minimum supported Unity version to 2019.1. + +## [1.3.0] - 2021-05-10 + +### Changed + +- Updated `FileUtility` and `ItchUploader` build actions to use new `BuildSettings.productParameters.buildVersion` property that deprecated `BuildSettings.productParameters.lastGeneratedVersion`. + +## [1.2.0] - 2021-04-29 + +### Added + +- Added `PerBuildAudioSettings` build action. + +## [1.1.0] - 2021-04-20 + +### Changed + +- Removed pre-Unity 2018.1 code. +- Disable `XRSettings` build action when XR Plug-in Management package is installed. + +## [1.0.0] - 2021-04-15 + +This release includes all [previous commits][1.0.0] to the project, plus: + +### Added + +- Added UPM support. +- First tagged version. +- Support use of `$VERSION` and `$BUILD` replacement tokens in single-run action paths in `FileUtility` action. +- Improved error reporting in `FileUtility` action. +- Added `$BASEPATH` to File and Folder path substitutions in `FileUtility` action. [PR #18](https://github.com/superunitybuild/buildactions/pull/18) +- Added input to customize channel names to `ItchUploader` action [PR #14](https://github.com/superunitybuild/buildactions/pull/14) + +### Changed + +- Support all versions of Unity XR Plug-in Management in `XRPluginManagement` action. + +### Fixed + +- `OverrideDefines` action no longer ignore pre build defines. [PR #17](https://github.com/superunitybuild/buildactions/pull/17) + +[unreleased]: https://github.com/superunitybuild/buildactions/compare/v4.0.1...HEAD +[4.0.1]: https://github.com/superunitybuild/buildactions/compare/v4.0.0...v4.0.1 +[4.0.0]: https://github.com/superunitybuild/buildactions/compare/v3.0.1...v4.0.0 +[3.0.1]: https://github.com/superunitybuild/buildactions/compare/v3.0.0...v3.0.1 +[3.0.0]: https://github.com/superunitybuild/buildactions/compare/v2.2.0...v3.0.0 +[2.2.0]: https://github.com/superunitybuild/buildactions/compare/v2.1.1...v2.2.0 +[2.1.1]: https://github.com/superunitybuild/buildactions/compare/v2.1.0...v2.1.1 +[2.1.0]: https://github.com/superunitybuild/buildactions/compare/v2.0.0...v2.1.0 +[2.0.0]: https://github.com/superunitybuild/buildactions/compare/v1.3.0...v2.0.0 +[1.3.0]: https://github.com/superunitybuild/buildactions/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/superunitybuild/buildactions/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/superunitybuild/buildactions/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/superunitybuild/buildactions/compare/5951d33...v1.0.0 diff --git a/CHANGELOG.md.meta b/CHANGELOG.md.meta new file mode 100644 index 0000000..fac9f98 --- /dev/null +++ b/CHANGELOG.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 386bdbb0465b39e40bb97a14c8f95b13 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityBuild-PackageManagement/Editor.meta b/Editor.meta similarity index 77% rename from UnityBuild-PackageManagement/Editor.meta rename to Editor.meta index d6bf2b8..50c8742 100644 --- a/UnityBuild-PackageManagement/Editor.meta +++ b/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 968e595265f54ae4fb71a48da5819f9b +guid: 8a5f4d2c7f042ff45b3d4e9faa1fd276 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/UnityBuild-AssetBundle.meta b/Editor/AssetBundle.meta similarity index 100% rename from UnityBuild-AssetBundle.meta rename to Editor/AssetBundle.meta diff --git a/Editor/AssetBundle/BuildAssetBundles.cs b/Editor/AssetBundle/BuildAssetBundles.cs new file mode 100644 index 0000000..e3a3838 --- /dev/null +++ b/Editor/AssetBundle/BuildAssetBundles.cs @@ -0,0 +1,89 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace SuperUnityBuild.BuildActions +{ + public sealed class BuildAssetBundles : BuildAction, IPreBuildPerPlatformAction + { + #region Public Variables + + [BuildTool.FilePath(true, true, "Select AssetBundle output directory.")] + public string baseBuildPath = Path.Combine("bin", "bundles"); + + public string innerBuildPath = Path.Combine("$PLATFORM", "$ARCHITECTURE"); + + public BuildAssetBundleOptions options = BuildAssetBundleOptions.ChunkBasedCompression; + + #endregion + + #region Public Methods + + public override void PerBuildExecute( + BuildReleaseType releaseType, + BuildPlatform platform, + BuildArchitecture architecture, + BuildScriptingBackend scriptingBackend, + BuildDistribution distribution, + DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + Build(platform, architecture); + } + + public void BuildAll() + { + string[] buildConfigs = BuildSettings.projectConfigurations.BuildAllKeychains(); + + for (int i = 0; i < buildConfigs.Length; i++) + { + BuildReleaseType releaseType; + BuildPlatform platform; + BuildArchitecture architecture; + BuildDistribution distribution; + BuildScriptingBackend scriptingBackend; + string configKey = buildConfigs[i]; + + BuildSettings.projectConfigurations.ParseKeychain(configKey, out releaseType, out platform, out architecture, out scriptingBackend, out distribution); + Build(platform, architecture); + } + } + + protected override void DrawProperties(SerializedObject obj) + { + EditorGUILayout.PropertyField(obj.FindProperty("baseBuildPath")); + EditorGUILayout.PropertyField(obj.FindProperty("innerBuildPath")); + options = (BuildAssetBundleOptions)EditorGUILayout.EnumFlagsField("Options", options); + + if (GUILayout.Button("Run Now", GUILayout.ExpandWidth(true))) + BuildAll(); + } + + #endregion + + #region Private Methods + + private void Build(BuildPlatform platform, BuildArchitecture architecture) + { + if (!platform.enabled || !architecture.enabled) + return; + + // Resolve build path. + string platformBundlePath = TokensUtility.ResolveBuildConfigurationTokens( + Path.Combine(baseBuildPath, innerBuildPath), + null, platform, architecture, null, null, null + ); + + // Create build destination directory if it does not exist. + if (!Directory.Exists(platformBundlePath)) + Directory.CreateDirectory(platformBundlePath); + + // Build AssetBundles. + BuildPipeline.BuildAssetBundles(platformBundlePath, options, architecture.target); + } + + #endregion + } +} diff --git a/UnityBuild-AssetBundle/Editor/BuildAssetBundles.cs.meta b/Editor/AssetBundle/BuildAssetBundles.cs.meta similarity index 100% rename from UnityBuild-AssetBundle/Editor/BuildAssetBundles.cs.meta rename to Editor/AssetBundle/BuildAssetBundles.cs.meta diff --git a/UnityBuild-AssetBundle/README.md b/Editor/AssetBundle/README.md similarity index 100% rename from UnityBuild-AssetBundle/README.md rename to Editor/AssetBundle/README.md diff --git a/UnityBuild-AssetBundle/README.md.meta b/Editor/AssetBundle/README.md.meta similarity index 100% rename from UnityBuild-AssetBundle/README.md.meta rename to Editor/AssetBundle/README.md.meta diff --git a/UnityBuild-FileUtility.meta b/Editor/FileUtility.meta similarity index 100% rename from UnityBuild-FileUtility.meta rename to Editor/FileUtility.meta diff --git a/Editor/FileUtility/FileOperation.cs b/Editor/FileUtility/FileOperation.cs new file mode 100644 index 0000000..89f05ad --- /dev/null +++ b/Editor/FileUtility/FileOperation.cs @@ -0,0 +1,173 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.IO; +using UnityEditor; + +namespace SuperUnityBuild.BuildActions +{ + using Operation = FileUtility.Operation; + + public class FileOperation : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor + { + [BuildTool.FilePath(false)] + public string inputPath; + [BuildTool.FilePath(false)] + public string outputPath; + public bool recursiveSearch = true; + public Operation operation; + + public override void Execute() + { + string resolvedInputPath = BuildAction.ResolveExecuteTokens(inputPath); + string resolvedOutputPath = BuildAction.ResolveExecuteTokens(outputPath); + + PerformOperation(resolvedInputPath, resolvedOutputPath); + } + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + string resolvedInputPath = BuildAction.ResolvePerBuildExecuteTokens(inputPath, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + string resolvedOutputPath = BuildAction.ResolvePerBuildExecuteTokens(outputPath, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + + PerformOperation(resolvedInputPath, resolvedOutputPath); + } + + protected override void DrawProperties(SerializedObject obj) + { + bool containsWildcard = FileUtility.ContainsWildcard(inputPath); + + EditorGUILayout.PropertyField(obj.FindProperty("operation")); + + if (containsWildcard) + EditorGUILayout.PropertyField(obj.FindProperty("recursiveSearch")); + + EditorGUILayout.PropertyField(obj.FindProperty("inputPath")); + + if (operation != Operation.Delete) + EditorGUILayout.PropertyField(obj.FindProperty("outputPath")); + } + + private void PerformOperation(string inputPath, string outputPath) + { + switch (operation) + { + case Operation.Copy: + Copy(inputPath, outputPath); + break; + case Operation.Move: + Move(inputPath, outputPath); + break; + case Operation.Delete: + Delete(inputPath); + break; + } + + AssetDatabase.Refresh(); + } + + private void Copy(string inputPath, string outputPath, bool overwrite = true) + { + CopyOrMove(true, inputPath, outputPath, overwrite); + } + + private void Move(string inputPath, string outputPath, bool overwrite = true) + { + CopyOrMove(false, inputPath, outputPath, overwrite); + } + + private void CopyOrMove(bool isCopy, string inputPath, string outputPath, bool overwrite = true) + { + Action fileOperation = FileUtility.GetCopyOrMoveAction(isCopy); + + bool success = true; + string errorString = ""; + bool containsWildcard = FileUtility.ContainsWildcard(inputPath); + + success = ValidatePath(inputPath, FileUtility.PathType.Input, !containsWildcard, out errorString); + + if (success) + success = ValidatePath(outputPath, FileUtility.PathType.Output, false, out errorString); + + if (success) + { + if (containsWildcard) + { + string outputDirectory = Path.GetDirectoryName(outputPath); + + WildcardOperation(inputPath, recursiveSearch, (string filePath) => + { + string fileName = Path.GetFileName(filePath); + string outputFile = Path.Combine(outputDirectory, fileName); + bool shouldContinue = true; + + if (File.Exists(outputFile)) + shouldContinue = FileUtility.Delete(outputFile, $"Could not overwrite existing file \"{outputFile}\".", out string errorString); + + if (shouldContinue) + fileOperation(filePath, outputFile); + + return shouldContinue; + }); + } + else + { + if (overwrite && File.Exists(outputPath)) + success = FileUtility.Delete(outputPath, $"Could not overwrite existing file \"{outputPath}\".", out errorString); + + if (success) + fileOperation(inputPath, outputPath); + } + } + + FileUtility.OperationComplete(success, $"File {(isCopy ? "Copy" : "Move")} Failed.", errorString); + } + + private void Delete(string inputPath) + { + bool success = true; + string errorString = ""; + bool containsWildcard = FileUtility.ContainsWildcard(inputPath); + + success = ValidatePath(inputPath, FileUtility.PathType.Input, true, out errorString); + + if (success) + { + success = containsWildcard ? + WildcardOperation(inputPath, recursiveSearch, (string filePath) => + FileUtility.Delete(filePath, $"Could not delete file \"{filePath}\".", out string errorString) + ) : + FileUtility.Delete(inputPath, $"Could not delete file \"{inputPath}\".", out errorString); + } + + FileUtility.OperationComplete(success, "File Delete Failed.", errorString); + } + + private bool ValidatePath(string path, FileUtility.PathType pathType, bool checkForExistence, out string errorString) + { + return FileUtility.ValidatePath(path, pathType, checkForExistence, true, out errorString); + } + + private static bool WildcardOperation(string path, bool recursiveSearch, Func operation) + { + bool success = false; + + string directory = Path.GetDirectoryName(path); + + SearchOption option = recursiveSearch ? + SearchOption.AllDirectories : + SearchOption.TopDirectoryOnly; + + string[] fileList = Directory.GetFiles(directory, Path.GetFileName(path), option); + + for (int i = 0; i < fileList.Length; i++) + { + success = operation.Invoke(fileList[i]); + + if (!success) + break; + } + + return success; + } + } +} diff --git a/UnityBuild-FileUtility/Editor/FileOperation.cs.meta b/Editor/FileUtility/FileOperation.cs.meta similarity index 100% rename from UnityBuild-FileUtility/Editor/FileOperation.cs.meta rename to Editor/FileUtility/FileOperation.cs.meta diff --git a/Editor/FileUtility/FileUtility.cs b/Editor/FileUtility/FileUtility.cs new file mode 100644 index 0000000..bd4b0f3 --- /dev/null +++ b/Editor/FileUtility/FileUtility.cs @@ -0,0 +1,83 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.IO; +using UnityEditor; + +namespace SuperUnityBuild.BuildActions +{ + public static class FileUtility + { + public enum Operation + { + Move, + Copy, + Delete, + } + + public enum PathType + { + Input, + Output + } + + public static bool ContainsWildcard(string inputPath) + { + return !string.IsNullOrEmpty(inputPath) && Path.GetFileNameWithoutExtension(inputPath).Contains("*"); + } + + public static bool Delete(string path, string failureErrorString, out string errorString) + { + errorString = ""; + + bool success = FileUtil.DeleteFileOrDirectory(path); + + if (!success) + errorString = failureErrorString; + + return success; + } + + public static Action GetCopyOrMoveAction(bool isCopy) + { + return isCopy ? + FileUtil.CopyFileOrDirectory : + FileUtil.MoveFileOrDirectory; + } + + public static void OperationComplete(bool success, string errorTitle, string errorString) + { + if (!success && !string.IsNullOrEmpty(errorString) && !string.IsNullOrEmpty(errorTitle)) + { + BuildNotificationList.instance.AddNotification(new BuildNotification( + BuildNotification.Category.Error, + errorTitle, errorString, + true, null)); + } + } + + public static bool ValidatePath(string path, FileUtility.PathType pathType, bool checkForExistence, bool isFile, out string errorString) + { + errorString = ""; + + if (string.IsNullOrEmpty(path)) + { + errorString = $"{pathType} path not specified."; + return false; + } + + if ( + checkForExistence && + ( + (isFile && !File.Exists(path)) || + (!isFile && !Directory.Exists(path)) + ) + ) + { + errorString = $"{pathType} path \"{path}\" does not exist."; + return false; + } + + return true; + } + } +} diff --git a/Editor/FileUtility/FileUtility.cs.meta b/Editor/FileUtility/FileUtility.cs.meta new file mode 100644 index 0000000..4e8d06d --- /dev/null +++ b/Editor/FileUtility/FileUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3d21a20ff9250845a5eab38a7ef9339 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/FileUtility/FolderOperation.cs b/Editor/FileUtility/FolderOperation.cs new file mode 100644 index 0000000..a8f2de9 --- /dev/null +++ b/Editor/FileUtility/FolderOperation.cs @@ -0,0 +1,119 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.IO; +using UnityEditor; + +namespace SuperUnityBuild.BuildActions +{ + using Operation = FileUtility.Operation; + + public class FolderOperation : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor + { + [BuildTool.FilePath(true)] + public string inputPath; + [BuildTool.FilePath(true)] + public string outputPath; + public Operation operation; + + public override void Execute() + { + string resolvedInputPath = BuildAction.ResolveExecuteTokens(inputPath); + string resolvedOutputPath = BuildAction.ResolveExecuteTokens(outputPath); + + PerformOperation(resolvedInputPath, resolvedOutputPath); + } + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + string resolvedInputPath = BuildAction.ResolvePerBuildExecuteTokens(inputPath, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + string resolvedOutputPath = BuildAction.ResolvePerBuildExecuteTokens(outputPath, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + + PerformOperation(resolvedInputPath, resolvedOutputPath); + } + + protected override void DrawProperties(SerializedObject obj) + { + EditorGUILayout.PropertyField(obj.FindProperty("operation")); + EditorGUILayout.PropertyField(obj.FindProperty("inputPath")); + + if (operation != Operation.Delete) + EditorGUILayout.PropertyField(obj.FindProperty("outputPath")); + } + + private void PerformOperation(string inputPath, string outputPath) + { + switch (operation) + { + case Operation.Copy: + Copy(inputPath, outputPath); + break; + case Operation.Move: + Move(inputPath, outputPath); + break; + case Operation.Delete: + Delete(inputPath); + break; + } + + AssetDatabase.Refresh(); + } + + private void Copy(string inputPath, string outputPath, bool overwrite = true) + { + CopyOrMove(true, inputPath, outputPath, overwrite); + } + + private void Move(string inputPath, string outputPath, bool overwrite = true) + { + CopyOrMove(false, inputPath, outputPath, overwrite); + } + + private void CopyOrMove(bool isCopy, string inputPath, string outputPath, bool overwrite = true) + { + Action fileOperation = FileUtility.GetCopyOrMoveAction(isCopy); + + bool success = true; + string errorString = ""; + + success = ValidatePath(inputPath, FileUtility.PathType.Input, true, out errorString); + + if (success) + success = ValidatePath(outputPath, FileUtility.PathType.Output, false, out errorString); + + if (success) + { + // Make sure that all parent directories in path are already created. + string parentPath = Path.GetDirectoryName(outputPath); + + if (!Directory.Exists(parentPath)) + Directory.CreateDirectory(parentPath); + + if (overwrite && Directory.Exists(outputPath)) + success = FileUtility.Delete(outputPath, $"Could not overwrite existing folder \"{outputPath}\".", out errorString); + + if (success) + fileOperation(inputPath, outputPath); + } + + FileUtility.OperationComplete(success, $"Folder {(isCopy ? "Copy" : "Move")} Failed.", errorString); + } + + private void Delete(string inputPath) + { + bool success = true; + string errorString = ""; + + success = ValidatePath(inputPath, FileUtility.PathType.Input, true, out errorString); + + if (success) + success = FileUtility.Delete(inputPath, $"Could not delete folder \"{inputPath}\".", out errorString); + + FileUtility.OperationComplete(success, "Folder Delete Failed.", errorString); + } + + private bool ValidatePath(string path, FileUtility.PathType pathType, bool checkForExistence, out string errorString) + { + return FileUtility.ValidatePath(path, pathType, checkForExistence, false, out errorString); + } + } +} diff --git a/UnityBuild-FileUtility/Editor/FolderOperation.cs.meta b/Editor/FileUtility/FolderOperation.cs.meta similarity index 100% rename from UnityBuild-FileUtility/Editor/FolderOperation.cs.meta rename to Editor/FileUtility/FolderOperation.cs.meta diff --git a/UnityBuild-FileUtility/README.md b/Editor/FileUtility/README.md similarity index 100% rename from UnityBuild-FileUtility/README.md rename to Editor/FileUtility/README.md diff --git a/UnityBuild-FileUtility/README.md.meta b/Editor/FileUtility/README.md.meta similarity index 100% rename from UnityBuild-FileUtility/README.md.meta rename to Editor/FileUtility/README.md.meta diff --git a/UnityBuild-ItchUploader.meta b/Editor/ItchUploader.meta similarity index 100% rename from UnityBuild-ItchUploader.meta rename to Editor/ItchUploader.meta diff --git a/UnityBuild-ItchUploader/README.md b/Editor/ItchUploader/README.md similarity index 100% rename from UnityBuild-ItchUploader/README.md rename to Editor/ItchUploader/README.md diff --git a/UnityBuild-ItchUploader/README.md.meta b/Editor/ItchUploader/README.md.meta similarity index 100% rename from UnityBuild-ItchUploader/README.md.meta rename to Editor/ItchUploader/README.md.meta diff --git a/Editor/ItchUploader/UploadItch.cs b/Editor/ItchUploader/UploadItch.cs new file mode 100644 index 0000000..480ded2 --- /dev/null +++ b/Editor/ItchUploader/UploadItch.cs @@ -0,0 +1,199 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace SuperUnityBuild.BuildActions +{ + public class UploadItch : BuildAction, IPostBuildPerPlatformAction + { + private const string WINDOWS = "windows"; + private const string OSX = "mac"; + private const string LINUX = "linux"; + private const string ANDROID = "android"; + private const string WEBGL = "webgl"; + private const string UWP = "uwp"; + + private const string ARCHITECTURE_X86 = "x86"; + private const string ARCHITECTURE_X64 = "x64"; + private const string ARCHITECTURE_UNIVERSAL = "universal"; + + [BuildTool.FilePath(false, true, "Path to butler.exe")] + public string pathToButlerExe = ""; + public string nameOfItchUser = ""; + public string nameOfItchGame = ""; + public bool useGeneratedBuildVersion = false; + + [Header("Channel name")] + public string channelName = "$PLATFORM-$ARCHITECTURE"; + + [Header("Disable to capture error output for debugging.")] + public bool showUploadProgress = true; + + [Header("Use with caution. Override applies to all platforms.")] + public string itchChannelOverride = ""; + + #region Public Methods + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + // Verify that butler executable exists. + if (!File.Exists(pathToButlerExe)) + { + UnityEngine.Debug.LogError("Couldn't find butler.exe file at path \"" + pathToButlerExe + "\", please check provided path"); + return; + } + + buildPath = Path.GetFullPath(buildPath); + + // Generate build args for the form: butler push {optional args} {build path} {itch username}/{itch game}:{channel} + StringBuilder scriptArguments = new StringBuilder("push "); + + switch (architecture.target) + { + case BuildTarget.StandaloneOSX: + case BuildTarget.StandaloneLinux64: + // Fix exe permissions for Linux/OSX. + scriptArguments.Append("--fix-permissions "); + break; + } + + if (useGeneratedBuildVersion) + { + // Append generated versions string. + scriptArguments.Append(string.Format("--userversion \"{0}\" ", BuildSettings.productParameters.buildVersion)); + } + + scriptArguments.Append("\"" + buildPath + "\"" + " " + nameOfItchUser + "/" + nameOfItchGame + ":"); + + scriptArguments.Append(!string.IsNullOrEmpty(itchChannelOverride) ? + itchChannelOverride : + GetChannelName(channelName, architecture.target, releaseType) + ); + + // UnityEngine.Debug.Log("Would have run itch uploader with following command line: \"" + pathToButlerExe + " " + scriptArguments + "\""); + RunScript(pathToButlerExe, scriptArguments.ToString()); + } + + #endregion + + #region Private Methods + + private void RunScript(string scriptPath, string arguments) + { + // Create and start butler process. + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.FileName = Path.GetFullPath(scriptPath); + startInfo.UseShellExecute = showUploadProgress; + startInfo.CreateNoWindow = !showUploadProgress; + startInfo.RedirectStandardOutput = !showUploadProgress; + startInfo.RedirectStandardError = !showUploadProgress; + + if (!string.IsNullOrEmpty(arguments)) + startInfo.Arguments = arguments; + + Process proc = Process.Start(startInfo); + + StringBuilder outputText = new StringBuilder(); + if (!showUploadProgress) + { + // Capture stdout. + proc.OutputDataReceived += (sendingProcess, outputLine) => + { + outputText.AppendLine(outputLine.Data); + }; + + proc.BeginOutputReadLine(); + } + + // Wait for butler to finish. + proc.WaitForExit(); + + // Display error if one occurred. + if (proc.ExitCode != 0) + { + string errString; + if (showUploadProgress) + { + errString = "Run w/ ShowUploadProgress disabled to capture debug output to console."; + } + else + { + errString = "Check console window for debug output."; + } + + BuildNotificationList.instance.AddNotification(new BuildNotification( + BuildNotification.Category.Error, + "Itch Upload Failed.", string.Format("Exit code: {0}\n{1}", proc.ExitCode, errString), + true, null)); + + UnityEngine.Debug.Log("ITCH.IO BUTLER OUTPUT: " + outputText.ToString()); + } + } + + private static string GetChannelName(string channelNameFormat, BuildTarget target, BuildReleaseType buildReleaseType) + { + string platform = string.Empty; + string architecture = string.Empty; + + switch (target) + { + // Windows + case BuildTarget.StandaloneWindows: + platform = WINDOWS; + architecture = ARCHITECTURE_X86; + break; + case BuildTarget.StandaloneWindows64: + platform = WINDOWS; + architecture = ARCHITECTURE_X64; + break; + + // Linux + case BuildTarget.StandaloneLinux64: + platform = LINUX; + architecture = ARCHITECTURE_X64; + break; + + // OSX + case BuildTarget.StandaloneOSX: + platform = OSX; + architecture = ARCHITECTURE_UNIVERSAL; + break; + + // Android + case BuildTarget.Android: + platform = ANDROID; + architecture = ARCHITECTURE_UNIVERSAL; + break; + + // WebGL + case BuildTarget.WebGL: + platform = WEBGL; + break; + + // UWP + case BuildTarget.WSAPlayer: + platform = UWP; + architecture = EditorUserBuildSettings.wsaArchitecture; + break; + + // Other + default: + UnityEngine.Debug.LogWarning("UploadItch: The current BuildTarget doesn't appear to be a standard Itch.IO build target."); + platform = target.ToString().ToLower(); + break; + } + + return channelNameFormat + .Replace("$PLATFORM", platform) + .Replace("$ARCHITECTURE", architecture) + .Replace("$RELEASE_TYPE", buildReleaseType.typeName) + .Trim('-'); + } + + #endregion + } +} diff --git a/UnityBuild-ItchUploader/Editor/UploadItch.cs.meta b/Editor/ItchUploader/UploadItch.cs.meta similarity index 100% rename from UnityBuild-ItchUploader/Editor/UploadItch.cs.meta rename to Editor/ItchUploader/UploadItch.cs.meta diff --git a/UnityBuild-OverrideDefines.meta b/Editor/OverrideDefines.meta similarity index 100% rename from UnityBuild-OverrideDefines.meta rename to Editor/OverrideDefines.meta diff --git a/Editor/OverrideDefines/OverrideDefines.cs b/Editor/OverrideDefines/OverrideDefines.cs new file mode 100644 index 0000000..10b405e --- /dev/null +++ b/Editor/OverrideDefines/OverrideDefines.cs @@ -0,0 +1,45 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.Text; +using UnityEditor; + +namespace SuperUnityBuild.BuildActions +{ + public class OverrideDefines : BuildAction, IPreBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor + { + public string removeDefines; + public string addDefines; + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + string preBuildDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(platform.targetGroup); + string defaultDefines = BuildProject.GenerateDefaultDefines(releaseType, platform, architecture, scriptingBackend, distribution); + + StringBuilder mergedDefines = new StringBuilder(BuildProject.MergeDefines(preBuildDefines, defaultDefines)); + + if (!string.IsNullOrEmpty(removeDefines)) + { + string resolvedRemove = TokensUtility.ResolveBuildConfigurationTokens(removeDefines, releaseType, platform, architecture, scriptingBackend, distribution, buildTime); + string[] splitRemove = resolvedRemove.Split(';'); + + for (int i = 0; i < splitRemove.Length; i++) + { + mergedDefines.Replace(splitRemove[i] + ";", ""); + mergedDefines.Replace(splitRemove[i], ""); + } + } + + if (!string.IsNullOrEmpty(addDefines)) + { + string resolvedAdd = TokensUtility.ResolveBuildConfigurationTokens(addDefines, releaseType, platform, architecture, scriptingBackend, distribution, buildTime); + + if (mergedDefines.Length > 0) + mergedDefines.Append(";"); + + mergedDefines.Append(resolvedAdd); + } + + PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, mergedDefines.ToString()); + } + } +} diff --git a/UnityBuild-OverrideDefines/Editor/OverrideDefines.cs.meta b/Editor/OverrideDefines/OverrideDefines.cs.meta similarity index 100% rename from UnityBuild-OverrideDefines/Editor/OverrideDefines.cs.meta rename to Editor/OverrideDefines/OverrideDefines.cs.meta diff --git a/UnityBuild-OverrideDefines/README.md b/Editor/OverrideDefines/README.md similarity index 100% rename from UnityBuild-OverrideDefines/README.md rename to Editor/OverrideDefines/README.md diff --git a/UnityBuild-OverrideDefines/README.md.meta b/Editor/OverrideDefines/README.md.meta similarity index 77% rename from UnityBuild-OverrideDefines/README.md.meta rename to Editor/OverrideDefines/README.md.meta index 2e959b3..9e8ca37 100644 --- a/UnityBuild-OverrideDefines/README.md.meta +++ b/Editor/OverrideDefines/README.md.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e406c2ed22747424ca6f2682096c9598 +guid: b851c3c4eb32fb0409d0acf4df45d0b0 timeCreated: 1511119362 licenseType: Pro DefaultImporter: diff --git a/UnityBuild-PackageManagement.meta b/Editor/PackageManagement.meta similarity index 100% rename from UnityBuild-PackageManagement.meta rename to Editor/PackageManagement.meta diff --git a/UnityBuild-PackageManagement/Editor/PackageManagement.cs b/Editor/PackageManagement/PackageManagement.cs similarity index 83% rename from UnityBuild-PackageManagement/Editor/PackageManagement.cs rename to Editor/PackageManagement/PackageManagement.cs index 1eef042..dd39da5 100644 --- a/UnityBuild-PackageManagement/Editor/PackageManagement.cs +++ b/Editor/PackageManagement/PackageManagement.cs @@ -1,19 +1,19 @@ +using SuperUnityBuild.BuildTool; using System; using System.Collections.Generic; using UnityEditor; using UnityEditor.PackageManager; using UnityEditor.PackageManager.Requests; using UnityEngine; - -namespace SuperSystems.UnityBuild +namespace SuperUnityBuild.BuildActions { - public class PackageManagement : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction + public class PackageManagement : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor { [Header("Package Settings")] [Tooltip("List of package IDs to add")] public List PackagesToAdd = new List(); [Tooltip("List of package IDs to remove")] public List PackagesToRemove = new List(); - public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) { PackagesToRemove.ForEach(id => HandleRequest(Client.Remove(id), id)); diff --git a/UnityBuild-PackageManagement/Editor/PackageManagement.cs.meta b/Editor/PackageManagement/PackageManagement.cs.meta similarity index 100% rename from UnityBuild-PackageManagement/Editor/PackageManagement.cs.meta rename to Editor/PackageManagement/PackageManagement.cs.meta diff --git a/UnityBuild-PackageManagement/README.md b/Editor/PackageManagement/README.md similarity index 100% rename from UnityBuild-PackageManagement/README.md rename to Editor/PackageManagement/README.md diff --git a/UnityBuild-PackageManagement/README.md.meta b/Editor/PackageManagement/README.md.meta similarity index 100% rename from UnityBuild-PackageManagement/README.md.meta rename to Editor/PackageManagement/README.md.meta diff --git a/UnityBuild-ItchUploader/Editor.meta b/Editor/PerBuildAudioSettings.meta similarity index 58% rename from UnityBuild-ItchUploader/Editor.meta rename to Editor/PerBuildAudioSettings.meta index 3d4a651..0a5fd7c 100644 --- a/UnityBuild-ItchUploader/Editor.meta +++ b/Editor/PerBuildAudioSettings.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 -guid: cd74748590f989b43b9a07971630acaf +guid: 47cc0554148cb444389b0b3cb29e59e1 folderAsset: yes -timeCreated: 1483567647 -licenseType: Pro DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Editor/PerBuildAudioSettings/PerBuildAudioSettings.cs b/Editor/PerBuildAudioSettings/PerBuildAudioSettings.cs new file mode 100644 index 0000000..1e9a415 --- /dev/null +++ b/Editor/PerBuildAudioSettings/PerBuildAudioSettings.cs @@ -0,0 +1,44 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.Linq; +using UnityEditor; +using UnityEngine; + +namespace SuperUnityBuild.BuildActions +{ + public class PerBuildAudioSettings : BuildAction, IPreBuildPerPlatformAction, IPostBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor + { + [Tooltip("Spatializer plugin to use for this build")] public string SpatializerPlugin = ""; + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + // Set spatializer plugin + AudioSettings.SetSpatializerPluginName(SpatializerPlugin); + } + + private int index = 0; + private string[] spatializerPluginNames; + + private void OnEnable() + { + spatializerPluginNames = AudioSettings.GetSpatializerPluginNames(); + spatializerPluginNames = spatializerPluginNames.Prepend("None").ToArray(); + index = Math.Max(Array.IndexOf(spatializerPluginNames, SpatializerPlugin), 0); + } + + protected override void DrawProperty(SerializedProperty prop) + { + switch (prop.name) + { + case "SpatializerPlugin": + index = EditorGUILayout.Popup(prop.displayName, index, spatializerPluginNames); + prop.stringValue = index == 0 ? "" : spatializerPluginNames[index]; + break; + + default: + base.DrawProperty(prop); + break; + } + } + } +} diff --git a/Editor/PerBuildAudioSettings/PerBuildAudioSettings.cs.meta b/Editor/PerBuildAudioSettings/PerBuildAudioSettings.cs.meta new file mode 100644 index 0000000..97d6a68 --- /dev/null +++ b/Editor/PerBuildAudioSettings/PerBuildAudioSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c5380d77f3977b4b9d57468c981ecf0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/PerBuildAudioSettings/README.md b/Editor/PerBuildAudioSettings/README.md new file mode 100644 index 0000000..0dee549 --- /dev/null +++ b/Editor/PerBuildAudioSettings/README.md @@ -0,0 +1,3 @@ +# SuperUnityBuild - Per-build Audio Settings + +> Enable per-build Audio settings diff --git a/Editor/PerBuildAudioSettings/README.md.meta b/Editor/PerBuildAudioSettings/README.md.meta new file mode 100644 index 0000000..c76c190 --- /dev/null +++ b/Editor/PerBuildAudioSettings/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 364c15a17c374344eb5cf45a4e088acc +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityBuild-FileUtility/Editor.meta b/Editor/PerBuildPlayerSettings.meta similarity index 58% rename from UnityBuild-FileUtility/Editor.meta rename to Editor/PerBuildPlayerSettings.meta index 5c89fe5..5f90021 100644 --- a/UnityBuild-FileUtility/Editor.meta +++ b/Editor/PerBuildPlayerSettings.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 -guid: 6d800d3142e46c84f94422e9e2e76055 +guid: 6024b0d2dc11f6d4e8a3a0db6deae015 folderAsset: yes -timeCreated: 1484084208 -licenseType: Pro DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Editor/PerBuildPlayerSettings/PerBuildPlayerSettings.cs b/Editor/PerBuildPlayerSettings/PerBuildPlayerSettings.cs new file mode 100644 index 0000000..44f25b4 --- /dev/null +++ b/Editor/PerBuildPlayerSettings/PerBuildPlayerSettings.cs @@ -0,0 +1,51 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace SuperUnityBuild.BuildActions +{ + public class PerBuildPlayerSettings : BuildAction, IPreBuildPerPlatformAction, IPostBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor + { + [Header("Resolution")] + public FullScreenMode fullScreenMode; + public bool defaultIsNativeResolution; + public int defaultScreenWidth = 800; + public int defaultScreenHeight = 600; + public bool runInBackground; + [Header("Standalone Player Options")] + public bool resizableWindow; + public bool visibleInBackground = true; + public bool allowFullscreenSwitch; + + [Header("Other Settings")] + [Tooltip("Preloaded assets to set for this build")] public List PreloadedAssets = new List(); + [Tooltip("Whether or not to preserve existing preloaded assets")] public bool PreservePreloadedAssets = true; + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + // Set resolution & presentation config + PlayerSettings.fullScreenMode = fullScreenMode; + PlayerSettings.defaultIsNativeResolution = defaultIsNativeResolution; + PlayerSettings.defaultScreenHeight = defaultScreenHeight; + PlayerSettings.defaultScreenWidth = defaultScreenWidth; + PlayerSettings.runInBackground = runInBackground; + PlayerSettings.resizableWindow = resizableWindow; + PlayerSettings.allowFullscreenSwitch = allowFullscreenSwitch; + PlayerSettings.visibleInBackground = visibleInBackground; + + // Set preloaded assets + Object[] preloadedAssets = PlayerSettings.GetPreloadedAssets(); + + List preloadedAssetsList = PreservePreloadedAssets ? + preloadedAssets.ToList() : + new List(); + + preloadedAssetsList.AddRange(PreloadedAssets); + PlayerSettings.SetPreloadedAssets(preloadedAssetsList.ToArray()); + } + } +} diff --git a/Editor/PerBuildPlayerSettings/PerBuildPlayerSettings.cs.meta b/Editor/PerBuildPlayerSettings/PerBuildPlayerSettings.cs.meta new file mode 100644 index 0000000..cf32b17 --- /dev/null +++ b/Editor/PerBuildPlayerSettings/PerBuildPlayerSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b89407e197689243b5ebba8cc90bd9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/PerBuildPlayerSettings/README.md b/Editor/PerBuildPlayerSettings/README.md new file mode 100644 index 0000000..b96fc93 --- /dev/null +++ b/Editor/PerBuildPlayerSettings/README.md @@ -0,0 +1,2 @@ +# SuperUnityBuild - Per-build Player Settings +> Enable per-build Player settings diff --git a/Editor/PerBuildPlayerSettings/README.md.meta b/Editor/PerBuildPlayerSettings/README.md.meta new file mode 100644 index 0000000..23d02e3 --- /dev/null +++ b/Editor/PerBuildPlayerSettings/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e4ac8e39b469e4a42a4df8d7d890d758 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityBuild-ScriptRunner.meta b/Editor/ScriptRunner.meta similarity index 100% rename from UnityBuild-ScriptRunner.meta rename to Editor/ScriptRunner.meta diff --git a/UnityBuild-ScriptRunner/README.md b/Editor/ScriptRunner/README.md similarity index 100% rename from UnityBuild-ScriptRunner/README.md rename to Editor/ScriptRunner/README.md diff --git a/UnityBuild-ScriptRunner/README.md.meta b/Editor/ScriptRunner/README.md.meta similarity index 100% rename from UnityBuild-ScriptRunner/README.md.meta rename to Editor/ScriptRunner/README.md.meta diff --git a/Editor/ScriptRunner/ScriptRunner.cs b/Editor/ScriptRunner/ScriptRunner.cs new file mode 100644 index 0000000..a3bcc70 --- /dev/null +++ b/Editor/ScriptRunner/ScriptRunner.cs @@ -0,0 +1,43 @@ +using SuperUnityBuild.BuildTool; +using System; +using System.Diagnostics; +using System.IO; +using UnityEditor; + +namespace SuperUnityBuild.BuildActions +{ + public class ScriptRunner : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor + { + [BuildTool.FilePath(false, true, "Select program/script to run.")] + public string scriptPath = ""; + public string scriptArguments = ""; + + public override void Execute() + { + string resolvedScriptPath = BuildAction.ResolveExecuteTokens(scriptPath); + string resolvedScriptArguments = BuildAction.ResolveExecuteTokens(scriptArguments); + + RunScript(resolvedScriptPath, resolvedScriptArguments); + } + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + string resolvedScriptPath = BuildAction.ResolvePerBuildExecuteTokens(scriptPath, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + string resolvedScriptArguments = BuildAction.ResolvePerBuildExecuteTokens(scriptArguments, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + + RunScript(resolvedScriptPath, resolvedScriptArguments); + } + + private void RunScript(string scriptPath, string arguments) + { + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.FileName = Path.GetFullPath(scriptPath); + + if (!string.IsNullOrEmpty(arguments)) + startInfo.Arguments = arguments; + + Process proc = Process.Start(startInfo); + proc.WaitForExit(); + } + } +} diff --git a/UnityBuild-ScriptRunner/Editor/ScriptRunner.cs.meta b/Editor/ScriptRunner/ScriptRunner.cs.meta similarity index 100% rename from UnityBuild-ScriptRunner/Editor/ScriptRunner.cs.meta rename to Editor/ScriptRunner/ScriptRunner.cs.meta diff --git a/Editor/SuperUnityBuild.BuildActions.Editor.asmdef b/Editor/SuperUnityBuild.BuildActions.Editor.asmdef new file mode 100644 index 0000000..731a31e --- /dev/null +++ b/Editor/SuperUnityBuild.BuildActions.Editor.asmdef @@ -0,0 +1,31 @@ +{ + "name": "SuperUnityBuild.BuildActions.Editor", + "rootNamespace": "SuperUnityBuild.BuildActions", + "references": [ + "GUID:bf7b7d9340660ea4495e1f45f0fc349d", + "GUID:e40ba710768534012815d3193fa296cb", + "GUID:f9fe0089ec81f4079af78eb2287a6163" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.xr.management", + "expression": "", + "define": "UNITY_XR_MANAGEMENT" + }, + { + "name": "com.unity.xr.management", + "expression": "4.0.0", + "define": "UNITY_XR_MANAGEMENT_400_OR_NEWER" + } + ], + "noEngineReferences": false +} diff --git a/Editor/SuperUnityBuild.BuildActions.Editor.asmdef.meta b/Editor/SuperUnityBuild.BuildActions.Editor.asmdef.meta new file mode 100644 index 0000000..df17054 --- /dev/null +++ b/Editor/SuperUnityBuild.BuildActions.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 02dcfce5c35187844bcd78f712fd00c6 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityBuild-OverrideDefines/Editor.meta b/Editor/XRPluginManagement.meta similarity index 58% rename from UnityBuild-OverrideDefines/Editor.meta rename to Editor/XRPluginManagement.meta index 865b709..5629be5 100644 --- a/UnityBuild-OverrideDefines/Editor.meta +++ b/Editor/XRPluginManagement.meta @@ -1,9 +1,8 @@ fileFormatVersion: 2 -guid: 594ad643f17f3db4cb2a8c8d26184fb9 +guid: 214b6ce806feef54fb9f62d13a2c0da4 folderAsset: yes -timeCreated: 1491855404 -licenseType: Pro DefaultImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Editor/XRPluginManagement/README.md b/Editor/XRPluginManagement/README.md new file mode 100644 index 0000000..160660d --- /dev/null +++ b/Editor/XRPluginManagement/README.md @@ -0,0 +1,2 @@ +# SuperUnityBuild - XR Plug-in Management +> Enable per-build [Unity XR Plug-in Management](https://docs.unity3d.com/Packages/com.unity.xr.management@latest) settings diff --git a/Editor/XRPluginManagement/README.md.meta b/Editor/XRPluginManagement/README.md.meta new file mode 100644 index 0000000..fd75e9d --- /dev/null +++ b/Editor/XRPluginManagement/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cb9abcce9505d194cbf5bde48d482cf4 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/XRPluginManagement/XRPluginManagement.cs b/Editor/XRPluginManagement/XRPluginManagement.cs new file mode 100644 index 0000000..fccdb6c --- /dev/null +++ b/Editor/XRPluginManagement/XRPluginManagement.cs @@ -0,0 +1,33 @@ +#if UNITY_XR_MANAGEMENT +using SuperUnityBuild.BuildTool; +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEditor.XR.Management; +using UnityEngine; +using UnityEngine.XR.Management; + +namespace SuperUnityBuild.BuildActions +{ + public class XRPluginManagement : BuildAction, IPreBuildPerPlatformAction, IPostBuildPerPlatformAction, IPreBuildPerPlatformActionCanConfigureEditor + { + [Header("XR Settings")] + [Tooltip("XR plugin loaders to use for this build")] public List XRPlugins = new List(); + [Tooltip("Whether or not to use automatic initialization of XR plugin loaders on startup")] public bool InitializeXROnStartup = true; + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) + { + XRGeneralSettings generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(platform.targetGroup); + XRManagerSettings settingsManager = generalSettings.Manager; + + generalSettings.InitManagerOnStart = InitializeXROnStartup; + +#if UNITY_XR_MANAGEMENT_400_OR_NEWER + settingsManager.TrySetLoaders(XRPlugins); +#else + settingsManager.loaders = XRPlugins; +#endif + } + } +} +#endif diff --git a/Editor/XRPluginManagement/XRPluginManagement.cs.meta b/Editor/XRPluginManagement/XRPluginManagement.cs.meta new file mode 100644 index 0000000..cdaa54a --- /dev/null +++ b/Editor/XRPluginManagement/XRPluginManagement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c5527d4e3b8c134c885a687264c8024 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityBuild-ZipFile.meta b/Editor/ZipFile.meta similarity index 100% rename from UnityBuild-ZipFile.meta rename to Editor/ZipFile.meta diff --git a/UnityBuild-ZipFile/Editor/Ionic.Zip.License.txt b/Editor/ZipFile/Ionic.Zip.License.txt similarity index 100% rename from UnityBuild-ZipFile/Editor/Ionic.Zip.License.txt rename to Editor/ZipFile/Ionic.Zip.License.txt diff --git a/UnityBuild-ZipFile/Editor/Ionic.Zip.License.txt.meta b/Editor/ZipFile/Ionic.Zip.License.txt.meta similarity index 100% rename from UnityBuild-ZipFile/Editor/Ionic.Zip.License.txt.meta rename to Editor/ZipFile/Ionic.Zip.License.txt.meta diff --git a/UnityBuild-ZipFile/Editor/Ionic.Zip.dll b/Editor/ZipFile/Ionic.Zip.dll similarity index 100% rename from UnityBuild-ZipFile/Editor/Ionic.Zip.dll rename to Editor/ZipFile/Ionic.Zip.dll diff --git a/UnityBuild-ZipFile/Editor/Ionic.Zip.dll.meta b/Editor/ZipFile/Ionic.Zip.dll.meta similarity index 55% rename from UnityBuild-ZipFile/Editor/Ionic.Zip.dll.meta rename to Editor/ZipFile/Ionic.Zip.dll.meta index 74d024b..6096990 100644 --- a/UnityBuild-ZipFile/Editor/Ionic.Zip.dll.meta +++ b/Editor/ZipFile/Ionic.Zip.dll.meta @@ -1,21 +1,30 @@ fileFormatVersion: 2 guid: f0d3c55c5daeb8b4aaadde69fcec4137 -timeCreated: 1483755431 -licenseType: Pro PluginImporter: - serializedVersion: 1 + externalObjects: {} + serializedVersion: 2 iconMap: {} executionOrder: {} + defineConstraints: [] isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 platformData: - Any: + - first: + Any: + second: enabled: 0 settings: {} - Editor: + - first: + Editor: Editor + second: enabled: 1 settings: DefaultValueInitialized: true - WindowsStoreApps: + - first: + Windows Store Apps: WindowsStoreApps + second: enabled: 0 settings: CPU: AnyCPU diff --git a/UnityBuild-ZipFile/README.md b/Editor/ZipFile/README.md similarity index 100% rename from UnityBuild-ZipFile/README.md rename to Editor/ZipFile/README.md diff --git a/UnityBuild-ZipFile/README.md.meta b/Editor/ZipFile/README.md.meta similarity index 100% rename from UnityBuild-ZipFile/README.md.meta rename to Editor/ZipFile/README.md.meta diff --git a/Editor/ZipFile/ZipFileOperation.cs b/Editor/ZipFile/ZipFileOperation.cs new file mode 100644 index 0000000..e56f725 --- /dev/null +++ b/Editor/ZipFile/ZipFileOperation.cs @@ -0,0 +1,66 @@ +using Ionic.Zip; +using SuperUnityBuild.BuildTool; +using System; +using System.IO; +using UnityEngine; + +namespace SuperUnityBuild.BuildActions +{ + public class ZipFileOperation : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction + { + public string inputPath = "$BUILDPATH"; + public string outputPath = "$BUILDPATH"; + public string outputFileName = "$PRODUCT_NAME-$RELEASE_TYPE-$YEAR_$MONTH_$DAY.zip"; + + public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildScriptingBackend scriptingBackend, BuildDistribution distribution, DateTime buildTime, ref UnityEditor.BuildOptions options, string configKey, string buildPath) + { + string combinedOutputPath = Path.Combine(outputPath, outputFileName); + string resolvedOutputPath = BuildAction.ResolvePerBuildExecuteTokens(combinedOutputPath, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + + string resolvedInputPath = BuildAction.ResolvePerBuildExecuteTokens(inputPath, releaseType, platform, architecture, scriptingBackend, distribution, buildTime, buildPath); + + if (!resolvedOutputPath.EndsWith(".zip")) + resolvedOutputPath += ".zip"; + + PerformZip(Path.GetFullPath(resolvedInputPath), Path.GetFullPath(resolvedOutputPath)); + } + + private void PerformZip(string inputPath, string outputPath) + { + try + { + if (!Directory.Exists(inputPath)) + { + BuildNotificationList.instance.AddNotification(new BuildNotification( + BuildNotification.Category.Error, + "Zip Operation Failed.", string.Format("Input path does not exist: {0}", inputPath), + true, null)); + return; + } + + // Make sure that all parent directories in path are already created. + string parentPath = Path.GetDirectoryName(outputPath); + if (!Directory.Exists(parentPath)) + { + Directory.CreateDirectory(parentPath); + } + + // Delete old file if it exists. + if (File.Exists(outputPath)) + File.Delete(outputPath); + + using (ZipFile zip = new ZipFile(outputPath)) + { + zip.ParallelDeflateThreshold = -1; // Parallel deflate is bugged in DotNetZip, so we need to disable it. + zip.UseZip64WhenSaving = Zip64Option.AsNecessary; + zip.AddDirectory(inputPath); + zip.Save(); + } + } + catch (Exception ex) + { + Debug.LogError(ex.ToString()); + } + } + } +} diff --git a/UnityBuild-ZipFile/Editor/ZipFileOperation.cs.meta b/Editor/ZipFile/ZipFileOperation.cs.meta similarity index 100% rename from UnityBuild-ZipFile/Editor/ZipFileOperation.cs.meta rename to Editor/ZipFile/ZipFileOperation.cs.meta diff --git a/README.md b/README.md index f5539ac..fa394b3 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,81 @@ -# SuperUnityBuild - BuildActions -> BuildActions for use with the [SuperUnityBuild][unitybuild] build automation tool. +# SuperUnityBuild BuildActions -BuildActions are one of the key components that make the [SuperUnityBuild][unitybuild] build automation tool flexible and powerful. Each one extends the capabilities of SuperUnityBuild and can be easily setup and customized to suit your needs, and if there's some other specialized functionality that your project needs, you can simply write your own BuildActions and integrate them into the build process. +[![openupm](https://img.shields.io/npm/v/com.github.superunitybuild.buildactions?label=openupm®istry_uri=https://package.openupm.com)][openupm-package] + +> BuildActions for use with the [SuperUnityBuild][buildtool] build automation tool. + +![Logo](https://raw.githubusercontent.com/superunitybuild/buildtool/gh-pages/Cover.png) + +[Unity Forums Thread][unity-forums-thread] | [Documentation Wiki][wiki] | [OpenUPM package][openupm-package] + +BuildActions are one of the key components that make the [SuperUnityBuild][buildtool] build automation tool flexible and powerful. Each one extends the capabilities of SuperUnityBuild and can be easily setup and customized to suit your needs, and if there's some other specialized functionality that your project needs, you can simply write your own BuildActions and integrate them into the build process. This repository is intended to serve as an ever expanding library of useful BuildActions as more of them are created. ## Basic Usage -If you don't already have SuperUnityBuild, get it from its [GitHub repository][unitybuild]. Then, do one of the following: +### Installation + +BuildActions requires SuperUnityBuild to be [installed](https://github.com/superunitybuild/buildtool#installation) in your project. + +Official releases of BuildActions can be installed via [Unity Package Manager](https://docs.unity3d.com/Packages/com.unity.package-manager-ui@latest/index.html) from the [OpenUPM](https://openupm.com) package registry. See [https://openupm.com/packages/com.github.superunitybuild.buildactions/][openupm-package] for installation options. + +You can also [download the source zip][download] of this repository and extract its contents into your Unity project's `Packages` directory to install BuildActions as an embedded package. -* [Download][download] this project and copy the folder for the tools you want into your project's Assets directory. -* Make this repository a git submodule within your project's Assets directory. +### Setup -Refer to the [SuperUnityBuild wiki][unitybuild-wiki] for basic information on how to setup, use, and create your own BuildActions. For specific details on one of the BuildActions featured here, refer to the README in its directory. +Refer to the [SuperUnityBuild wiki][wiki] for basic information on how to setup, use, and create your own BuildActions. For specific details on one of the BuildActions featured here, refer to the README in its directory. ## Tools -* [**AssetBundle Builder**][assetbundle] - AssetBundle building and file management. -* [**Script Runner**][scriptrunner] - Run batch/script files or other external applications. -* [**Zip File Utility**][zipfile] - Compress builds and other files into ZIP file format. -* [**File Operations Utility**][fileutil] - Perform basic file/folder operations like copy, move, and delete. -* [**itch.io Uploader**][itchuploader] - Upload builds to [itch.io](https://itch.io/). -* [**Define Modifier**][overridedefines] - Add/remove script defines. +- [**AssetBundle Builder**][assetbundle] - AssetBundle building and file management. +- [**Script Runner**][scriptrunner] - Run batch/script files or other external applications. +- [**Zip File Utility**][zipfile] - Compress builds and other files into ZIP file format. +- [**File Operations Utility**][fileutil] - Perform basic file/folder operations like copy, move, and delete. +- [**itch.io Uploader**][itchuploader] - Upload builds to [itch.io](https://itch.io/). +- [**Override Defines**][overridedefines] - Add/remove script defines. +- [**Package Management**][packagemanagement] - Enable per-build Unity Package Manager settings. +- [**Per-Build Player Settings**][perbuildplayersettings] - Enable per-build Player settings. +- [**XR Plug-in Management**][xrpluginmanagement] - Enable per-build [Unity XR Plug-in Management](https://docs.unity3d.com/Packages/com.unity.xr.management@latest) settings. ## Contributing + Bug reports, feature requests, and pull requests are welcome and appreciated. ## Credits -* **Chase Pettit** - [github](https://github.com/Chaser324), [twitter](http://twitter.com/chasepettit) -## License -All code in this repository ([unity-build-actions](https://github.com/Chaser324/unity-build-actions)) is made freely available under the MIT license. This essentially means you're free to use it however you like as long as you provide attribution. +### Creator -Zip File Utility includes a pre-compiled DotNetZip library which is licensed under the Ms-PL. See [DotNetZip's repository](https://dotnetzip.codeplex.com/) for more info. +- **Chase Pettit** - [GitHub](https://github.com/Chaser324), [Twitter](http://twitter.com/chasepettit) +### Maintainer +- **Robin North** - [GitHub](https://github.com/robinnorth) +### Contributors +You can see a complete list of contributors at [https://github.com/superunitybuild/buildactions/graphs/contributors][contributors] -[download]: https://github.com/Chaser324/unity-build-actions/archive/master.zip -[unitybuild]: https://github.com/Chaser324/unity-build -[unitybuild-wiki]: https://github.com/Chaser324/unity-build/wiki/Build-Actions +## License + +All code in this repository ([buildactions](https://github.com/superunitybuild/buildactions)) is made freely available under the MIT license. This essentially means you're free to use it however you like as long as you provide attribution. + +Zip File Utility includes a pre-compiled DotNetZip library which is licensed under the Ms-PL. See [DotNetZip's repository](https://dotnetzip.codeplex.com/) for more info. -[assetbundle]: https://github.com/Chaser324/unity-build-actions/tree/master/UnityBuild-AssetBundle -[fileutil]: https://github.com/Chaser324/unity-build-actions/tree/master/UnityBuild-FileUtility -[scriptrunner]: https://github.com/Chaser324/unity-build-actions/tree/master/UnityBuild-ScriptRunner -[zipfile]: https://github.com/Chaser324/unity-build-actions/tree/master/UnityBuild-ZipFile -[itchuploader]: https://github.com/Chaser324/unity-build-actions/tree/master/UnityBuild-ItchUploader -[overridedefines]: https://github.com/Chaser324/unity-build-actions/tree/master/UnityBuild-OverrideDefines +[download]: https://github.com/superunitybuild/buildactions/archive/master.zip +[contributors]: https://github.com/superunitybuild/buildactions/graphs/contributors +[release]: https://github.com/superunitybuild/buildactions/releases +[buildtool]: https://github.com/superunitybuild/buildtool +[buildactions]: https://github.com/superunitybuild/buildactions +[wiki]: https://github.com/superunitybuild/buildtool/wiki/Build-Actions +[openupm-package]: https://openupm.com/packages/com.github.superunitybuild.buildactions/ +[unity-forums-thread]: https://forum.unity3d.com/threads/super-unity-build-automated-build-tool-and-framework.471114/ +[assetbundle]: https://github.com/superunitybuild/buildactions/tree/master/Editor/AssetBundle +[fileutil]: https://github.com/superunitybuild/buildactions/tree/master/Editor/FileUtility +[scriptrunner]: https://github.com/superunitybuild/buildactions/tree/master/Editor/ScriptRunner +[zipfile]: https://github.com/superunitybuild/buildactions/tree/master/Editor/ZipFile +[itchuploader]: https://github.com/superunitybuild/buildactions/tree/master/Editor/ItchUploader +[overridedefines]: https://github.com/superunitybuild/buildactions/tree/master/Editor/OverrideDefines +[packagemanagement]: https://github.com/superunitybuild/buildactions/tree/master/Editor/PackageManagement +[perbuildplayersettings]: https://github.com/superunitybuild/buildactions/tree/master/Editor/PerBuildPlayerSettings +[xrpluginmanagement]: https://github.com/superunitybuild/buildactions/tree/master/Editor/XRPluginManagement diff --git a/UnityBuild-AssetBundle/Editor.meta b/UnityBuild-AssetBundle/Editor.meta deleted file mode 100644 index 435aa56..0000000 --- a/UnityBuild-AssetBundle/Editor.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 6d6b1f2c66a18ae45842f8fcaaad1a2c -folderAsset: yes -timeCreated: 1483567638 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityBuild-AssetBundle/Editor/BuildAssetBundles.cs b/UnityBuild-AssetBundle/Editor/BuildAssetBundles.cs deleted file mode 100644 index 22f1e8f..0000000 --- a/UnityBuild-AssetBundle/Editor/BuildAssetBundles.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System.IO; -using System.Text; -using UnityEditor; -using UnityEngine; - -namespace SuperSystems.UnityBuild -{ - -public sealed class BuildAssetBundles : BuildAction, IPreBuildPerPlatformAction -{ - #region Public Variables - - [FilePath(true, true, "Select AssetBundle output directory.")] - public string baseBuildPath = Path.Combine("bin", "bundles"); - - public string innerBuildPath = Path.Combine("$PLATFORM", "$ARCHITECTURE"); - -#if UNITY_5_3 || UNITY_5_4_OR_NEWER - public BuildAssetBundleOptions options = BuildAssetBundleOptions.ChunkBasedCompression; -#else - public BuildAssetBundleOptions options = BuildAssetBundleOptions.None; -#endif - - #endregion - - #region Public Methods - - public override void PerBuildExecute( - BuildReleaseType releaseType, - BuildPlatform platform, - BuildArchitecture architecture, - BuildDistribution distribution, - System.DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) - { - Build(platform, architecture); - } - - public void BuildAll() - { - string[] buildConfigs = BuildSettings.projectConfigurations.BuildAllKeychains(); - - for (int i = 0; i < buildConfigs.Length; i++) - { - BuildReleaseType releaseType; - BuildPlatform platform; - BuildArchitecture arch; - BuildDistribution dist; - string configKey = buildConfigs[i]; - - BuildSettings.projectConfigurations.ParseKeychain(configKey, out releaseType, out platform, out arch, out dist); - Build(platform, arch); - } - } - - protected override void DrawProperties(SerializedObject obj) - { - EditorGUILayout.PropertyField(obj.FindProperty("baseBuildPath")); - EditorGUILayout.PropertyField(obj.FindProperty("innerBuildPath")); -#if UNITY_2017_3_OR_NEWER - options = (BuildAssetBundleOptions)EditorGUILayout.EnumFlagsField("Options", options); -#else - options = (BuildAssetBundleOptions)((int)(BuildAssetBundleOptions)EditorGUILayout.EnumMaskField("Options", (BuildAssetBundleOptions)((int)(options) << 1)) >> 1); -#endif - - if (GUILayout.Button("Run Now", GUILayout.ExpandWidth(true))) - { - BuildAll(); - } - } - - #endregion - - #region Private Methods - - private void Build(BuildPlatform platform, BuildArchitecture arch) - { - if (!platform.enabled || !arch.enabled) - return; - - // Resolve build path. - StringBuilder platformBundlePath = new StringBuilder(Path.Combine(baseBuildPath, innerBuildPath)); - platformBundlePath.Replace("$PLATFORM", BuildProject.SanitizeFolderName(platform.platformName)); - platformBundlePath.Replace("$ARCHITECTURE", BuildProject.SanitizeFolderName(arch.name)); - - // Create build destination directory if it does not exist. - if (!Directory.Exists(platformBundlePath.ToString())) - Directory.CreateDirectory(platformBundlePath.ToString()); - - // Build AssetBundles. - BuildPipeline.BuildAssetBundles(platformBundlePath.ToString(), options, arch.target); - } - - #endregion -} - -} \ No newline at end of file diff --git a/UnityBuild-FileUtility/Editor/FileOperation.cs b/UnityBuild-FileUtility/Editor/FileOperation.cs deleted file mode 100644 index bab3a6a..0000000 --- a/UnityBuild-FileUtility/Editor/FileOperation.cs +++ /dev/null @@ -1,188 +0,0 @@ -using UnityEngine; -using UnityEditor; -using System.Collections; -using System.IO; - -namespace SuperSystems.UnityBuild -{ - -public class FileOperation : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction -{ - public enum Operation - { - Move, - Copy, - Delete, - } - - [FilePath(false)] - public string inputPath; - [FilePath(false)] - public string outputPath; - public bool recursiveSearch = true; - public Operation operation; - - public override void Execute() - { - switch (operation) - { - case Operation.Copy: - Copy(inputPath, outputPath); - break; - case Operation.Move: - Move(inputPath, outputPath); - break; - case Operation.Delete: - Delete(inputPath); - break; - } - - AssetDatabase.Refresh(); - } - - public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, System.DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) - { - string resolvedInputPath = BuildProject.ResolvePath(inputPath.Replace("$BUILDPATH", buildPath), releaseType, platform, architecture, distribution, buildTime); - string resolvedOutputPath = BuildProject.ResolvePath(outputPath.Replace("$BUILDPATH", buildPath), releaseType, platform, architecture, distribution, buildTime); - - switch (operation) - { - case Operation.Copy: - Copy(resolvedInputPath, resolvedOutputPath); - break; - case Operation.Move: - Move(resolvedInputPath, resolvedOutputPath); - break; - case Operation.Delete: - Delete(resolvedInputPath); - break; - } - - AssetDatabase.Refresh(); - } - - protected override void DrawProperties(SerializedObject obj) - { - bool containsWildcard = string.IsNullOrEmpty(inputPath) ? false : Path.GetFileNameWithoutExtension(inputPath).Contains("*"); - - EditorGUILayout.PropertyField(obj.FindProperty("operation")); - - if (containsWildcard) - EditorGUILayout.PropertyField(obj.FindProperty("recursiveSearch")); - - EditorGUILayout.PropertyField(obj.FindProperty("inputPath")); - - if (operation != Operation.Delete) - EditorGUILayout.PropertyField(obj.FindProperty("outputPath")); - } - - private void Move(string inputPath, string outputPath, bool overwrite = true) - { - bool containsWildcard = string.IsNullOrEmpty(inputPath) ? false : Path.GetFileNameWithoutExtension(inputPath).Contains("*"); - - if (!containsWildcard && !File.Exists(inputPath)) - { - // Error. Input does not exist. - return; - } - - if (!containsWildcard && overwrite && File.Exists(outputPath)) - { - // Delete previous output. - FileUtil.DeleteFileOrDirectory(outputPath); - } - - if (containsWildcard) - { - string inputDirectory = Path.GetDirectoryName(inputPath); - string outputDirectory = Path.GetDirectoryName(outputPath); - - SearchOption option = recursiveSearch ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - string[] fileList = Directory.GetFiles(inputDirectory, Path.GetFileName(inputPath), option); - - for (int i = 0; i < fileList.Length; i++) - { - string fileName = Path.GetFileName(fileList[i]); - string outputFile = Path.Combine(outputDirectory, fileName); - - if (File.Exists(outputFile)) - FileUtil.DeleteFileOrDirectory(outputFile); - - FileUtil.MoveFileOrDirectory(fileList[i], outputFile); - } - } - else - { - FileUtil.MoveFileOrDirectory(inputPath, outputPath); - } - } - - private void Copy(string inputPath, string outputPath, bool overwrite = true) - { - bool containsWildcard = string.IsNullOrEmpty(inputPath) ? false : Path.GetFileNameWithoutExtension(inputPath).Contains("*"); - - if (!containsWildcard && !File.Exists(inputPath)) - { - // Error. Input does not exist. - return; - } - - if (!containsWildcard && overwrite && File.Exists(outputPath)) - { - // Delete previous output. - FileUtil.DeleteFileOrDirectory(outputPath); - } - - if (containsWildcard) - { - string inputDirectory = Path.GetDirectoryName(inputPath); - string outputDirectory = Path.GetDirectoryName(outputPath); - - SearchOption option = recursiveSearch ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - string[] fileList = Directory.GetFiles(inputDirectory, Path.GetFileName(inputPath), option); - - for (int i = 0; i < fileList.Length; i++) - { - string fileName = Path.GetFileName(fileList[i]); - string outputFile = Path.Combine(outputDirectory, fileName); - - if (File.Exists(outputFile)) - FileUtil.DeleteFileOrDirectory(outputFile); - - FileUtil.CopyFileOrDirectory(fileList[i], outputFile); - } - } - else - { - FileUtil.CopyFileOrDirectory(inputPath, outputPath); - } - } - - private void Delete(string inputPath) - { - bool containsWildcard = string.IsNullOrEmpty(inputPath) ? false : Path.GetFileNameWithoutExtension(inputPath).Contains("*"); - - if (!containsWildcard && File.Exists(inputPath)) - { - FileUtil.DeleteFileOrDirectory(inputPath); - } - else if (containsWildcard) - { - string inputDirectory = Path.GetDirectoryName(inputPath); - - SearchOption option = recursiveSearch ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - string[] fileList = Directory.GetFiles(inputDirectory, Path.GetFileName(inputPath), option); - - for (int i = 0; i < fileList.Length; i++) - { - FileUtil.DeleteFileOrDirectory(fileList[i]); - } - } - else - { - // Error. File does not exist. - } - } -} - -} \ No newline at end of file diff --git a/UnityBuild-FileUtility/Editor/FolderOperation.cs b/UnityBuild-FileUtility/Editor/FolderOperation.cs deleted file mode 100644 index 79ae2f5..0000000 --- a/UnityBuild-FileUtility/Editor/FolderOperation.cs +++ /dev/null @@ -1,177 +0,0 @@ -using UnityEngine; -using UnityEditor; -using System.Collections; -using System.IO; -using System.Diagnostics; - -namespace SuperSystems.UnityBuild -{ - -public class FolderOperation : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction -{ - public enum Operation - { - Move, - Copy, - Delete, - } - - [FilePath(true)] - public string inputPath; - [FilePath(true)] - public string outputPath; - public Operation operation; - - public override void Execute() - { - switch (operation) - { - case Operation.Copy: - Copy(inputPath, outputPath); - break; - case Operation.Move: - Move(inputPath, outputPath); - break; - case Operation.Delete: - Delete(inputPath); - break; - } - - AssetDatabase.Refresh(); - } - - public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, System.DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) - { - string resolvedInputPath = BuildProject.ResolvePath(inputPath.Replace("$BUILDPATH", buildPath), releaseType, platform, architecture, distribution, buildTime); - string resolvedOutputPath = BuildProject.ResolvePath(outputPath.Replace("$BUILDPATH", buildPath), releaseType, platform, architecture, distribution, buildTime); - - switch (operation) - { - case Operation.Copy: - Copy(resolvedInputPath, resolvedOutputPath); - break; - case Operation.Move: - Move(resolvedInputPath, resolvedOutputPath); - break; - case Operation.Delete: - Delete(resolvedInputPath); - break; - } - - AssetDatabase.Refresh(); - } - - protected override void DrawProperties(SerializedObject obj) - { - EditorGUILayout.PropertyField(obj.FindProperty("operation")); - EditorGUILayout.PropertyField(obj.FindProperty("inputPath")); - - if (operation != Operation.Delete) - EditorGUILayout.PropertyField(obj.FindProperty("outputPath")); - } - - private void Move(string inputPath, string outputPath, bool overwrite = true) - { - bool success = true; - string errorString = ""; - - if (!Directory.Exists(inputPath)) - { - // Error. Input does not exist. - success = false; - errorString = "Input does not exist."; - } - - // Make sure that all parent directories in path are already created. - string parentPath = Path.GetDirectoryName(outputPath); - if (!Directory.Exists(parentPath)) - { - Directory.CreateDirectory(parentPath); - } - - if (overwrite && Directory.Exists(outputPath)) - { - // Delete previous output. - success = FileUtil.DeleteFileOrDirectory(outputPath); - - if (!success) - errorString = "Could not overwrite existing folder."; - } - - FileUtil.MoveFileOrDirectory(inputPath, outputPath); - - if (!success && !string.IsNullOrEmpty(errorString)) - { - BuildNotificationList.instance.AddNotification(new BuildNotification( - BuildNotification.Category.Error, - "Folder Move Failed.", errorString, - true, null)); - } - } - - private void Copy(string inputPath, string outputPath, bool overwrite = true) - { - bool success = true; - string errorString = ""; - - if (!Directory.Exists(inputPath)) - { - // Error. Input does not exist. - success = false; - errorString = "Input does not exist."; - } - - // Make sure that all parent directories in path are already created. - string parentPath = Path.GetDirectoryName(outputPath); - if (!Directory.Exists(parentPath)) - { - Directory.CreateDirectory(parentPath); - } - - if (success && overwrite && Directory.Exists(outputPath)) - { - // Delete previous output. - success = FileUtil.DeleteFileOrDirectory(outputPath); - - if (!success) - errorString = "Could not overwrite existing folder."; - } - - FileUtil.CopyFileOrDirectory(inputPath, outputPath); - - if (!success && !string.IsNullOrEmpty(errorString)) - { - BuildNotificationList.instance.AddNotification(new BuildNotification( - BuildNotification.Category.Error, - "Folder Copy Failed.", errorString, - true, null)); - } - } - - private void Delete(string inputPath) - { - bool success = true; - string errorString = ""; - - if (Directory.Exists(inputPath)) - { - FileUtil.DeleteFileOrDirectory(inputPath); - } - else - { - // Error. File does not exist. - success = false; - errorString = "Input does not exist."; - } - - if (!success && !string.IsNullOrEmpty(errorString)) - { - BuildNotificationList.instance.AddNotification(new BuildNotification( - BuildNotification.Category.Error, - "Folder Delete Failed.", errorString, - true, null)); - } - } -} - -} \ No newline at end of file diff --git a/UnityBuild-ItchUploader/Editor/UploadItch.cs b/UnityBuild-ItchUploader/Editor/UploadItch.cs deleted file mode 100644 index 52c507f..0000000 --- a/UnityBuild-ItchUploader/Editor/UploadItch.cs +++ /dev/null @@ -1,183 +0,0 @@ -using System.Diagnostics; -using System.IO; -using System.Text; -using UnityEditor; -using UnityEngine; - -namespace SuperSystems.UnityBuild -{ - -public class UploadItch : BuildAction, IPostBuildPerPlatformAction -{ - private const string WINDOWS = "windows"; - private const string OSX = "osx"; - private const string LINUX = "linux"; - - [FilePath(false, true, "Path to butler.exe")] - public string pathToButlerExe = ""; - public string nameOfItchUser = ""; - public string nameOfItchGame = ""; - public bool useGeneratedBuildVersion = false; - - [Header("Disable to capture error output for debugging.")] - public bool showUploadProgress = true; - - [Header("Use with caution. Override applies to all platforms.")] - public string itchChannelOverride = ""; - - #region Public Methods - - public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, System.DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) - { - // Verify that butler executable exists. - if (!File.Exists(pathToButlerExe)) - { - UnityEngine.Debug.LogError("Couldn't find butler.exe file at path \"" + pathToButlerExe + "\", please check provided path"); - return; - } - - buildPath = Path.GetFullPath(buildPath); - - // Generate build args for the form: butler push {optional args} {build path} {itch username}/{itch game}:{channel} - StringBuilder scriptArguments = new StringBuilder("push "); - - switch (architecture.target) - { -#if UNITY_2017_3_OR_NEWER - case BuildTarget.StandaloneOSX: -#else - case BuildTarget.StandaloneOSXIntel: - case BuildTarget.StandaloneOSXIntel64: - case BuildTarget.StandaloneOSXUniversal: -#endif - case BuildTarget.StandaloneLinux: - case BuildTarget.StandaloneLinux64: - case BuildTarget.StandaloneLinuxUniversal: - // Fix exe permissions for Linux/OSX. - scriptArguments.Append("--fix-permissions "); - break; - } - - if (useGeneratedBuildVersion) - { - // Append generated versions string. - scriptArguments.Append(string.Format("--userversion \"{0}\" ", BuildSettings.productParameters.lastGeneratedVersion)); - } - - scriptArguments.Append("\"" + buildPath + "\"" + " " + nameOfItchUser + "/" + nameOfItchGame + ":"); - - if (!string.IsNullOrEmpty(itchChannelOverride)) - { - scriptArguments.Append(itchChannelOverride); - } - else - { - string itchChannel = GetChannelName(architecture.target); - if(string.IsNullOrEmpty(itchChannel)) - { - UnityEngine.Debug.LogWarning("UploadItch: The current BuildTarget doesn't appear to be a standard Itch.IO build target."); - } - - scriptArguments.Append(itchChannel); - } - - // UnityEngine.Debug.Log("Would have run itch uploader with following command line: \"" + pathToButlerExe + " " + scriptArguments + "\""); - RunScript(pathToButlerExe, scriptArguments.ToString()); - } - - #endregion - - #region Private Methods - - private void RunScript(string scriptPath, string arguments) - { - // Create and start butler process. - ProcessStartInfo startInfo = new ProcessStartInfo(); - startInfo.FileName = Path.GetFullPath(scriptPath); - startInfo.UseShellExecute = showUploadProgress; - startInfo.CreateNoWindow = !showUploadProgress; - startInfo.RedirectStandardOutput = !showUploadProgress; - startInfo.RedirectStandardError = !showUploadProgress; - - if (!string.IsNullOrEmpty(arguments)) - startInfo.Arguments = arguments; - - Process proc = Process.Start(startInfo); - - StringBuilder outputText = new StringBuilder(); - if (!showUploadProgress) - { - // Capture stdout. - proc.OutputDataReceived += (sendingProcess, outputLine) => - { - outputText.AppendLine(outputLine.Data); - }; - - proc.BeginOutputReadLine(); - } - - // Wait for butler to finish. - proc.WaitForExit(); - - // Display error if one occurred. - if (proc.ExitCode != 0) - { - string errString; - if (showUploadProgress) - { - errString = "Run w/ ShowUploadProgress disabled to capture debug output to console."; - } - else - { - errString = "Check console window for debug output."; - } - - BuildNotificationList.instance.AddNotification(new BuildNotification( - BuildNotification.Category.Error, - "Itch Upload Failed.", string.Format("Exit code: {0}\n{1}", proc.ExitCode, errString), - true, null)); - - UnityEngine.Debug.Log("ITCH.IO BUTLER OUTPUT: " + outputText.ToString()); - } - } - - private static string GetChannelName(BuildTarget target) - { - switch (target) - { - // Windows - case BuildTarget.StandaloneWindows: - return WINDOWS + "-x86"; - case BuildTarget.StandaloneWindows64: - return WINDOWS + "-x64"; - - // Linux - case BuildTarget.StandaloneLinux: - return LINUX + "-x86"; - case BuildTarget.StandaloneLinux64: - return LINUX + "-x64"; - case BuildTarget.StandaloneLinuxUniversal: - return LINUX + "-universal"; - - // OSX -#if UNITY_2017_3_OR_NEWER - case BuildTarget.StandaloneOSX: - return OSX; -#else - case BuildTarget.StandaloneOSXIntel: - return OSX + "-intel"; - case BuildTarget.StandaloneOSXIntel64: - return OSX + "-intel64"; - case BuildTarget.StandaloneOSXUniversal: - return OSX + "-universal"; -#endif - - default: - return null; - } - } - - #endregion -} - -} \ No newline at end of file diff --git a/UnityBuild-OverrideDefines/Editor/OverrideDefines.cs b/UnityBuild-OverrideDefines/Editor/OverrideDefines.cs deleted file mode 100644 index 8daf3ac..0000000 --- a/UnityBuild-OverrideDefines/Editor/OverrideDefines.cs +++ /dev/null @@ -1,45 +0,0 @@ -using UnityEngine; -using UnityEditor; -using System.Collections; -using System.IO; -using System.Text; - -namespace SuperSystems.UnityBuild -{ - -public class OverrideDefines : BuildAction, IPreBuildPerPlatformAction -{ - public string removeDefines; - public string addDefines; - - public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, System.DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) - { - StringBuilder defines = new StringBuilder(BuildProject.GenerateDefaultDefines(releaseType, platform, architecture, distribution)); - - if (!string.IsNullOrEmpty(removeDefines)) - { - string resolvedRemove = BuildProject.ResolvePath(removeDefines, releaseType, platform, architecture, distribution, buildTime); - string[] splitRemove = resolvedRemove.Split(';'); - - for (int i = 0; i < splitRemove.Length; i++) - { - defines.Replace(splitRemove[i] + ";", ""); - defines.Replace(splitRemove[i], ""); - } - } - - if (!string.IsNullOrEmpty(addDefines)) - { - string resolvedAdd = BuildProject.ResolvePath(addDefines, releaseType, platform, architecture, distribution, buildTime); - - if (defines.Length > 0) - defines.Append(";" + resolvedAdd); - else - defines.Append(resolvedAdd); - } - - PlayerSettings.SetScriptingDefineSymbolsForGroup(platform.targetGroup, defines.ToString()); - } -} - -} diff --git a/UnityBuild-ScriptRunner/Editor.meta b/UnityBuild-ScriptRunner/Editor.meta deleted file mode 100644 index b4052ba..0000000 --- a/UnityBuild-ScriptRunner/Editor.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: d7977bd259a27564b82c7152659db9a7 -folderAsset: yes -timeCreated: 1484084226 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityBuild-ScriptRunner/Editor/ScriptRunner.cs b/UnityBuild-ScriptRunner/Editor/ScriptRunner.cs deleted file mode 100644 index 84ad2f2..0000000 --- a/UnityBuild-ScriptRunner/Editor/ScriptRunner.cs +++ /dev/null @@ -1,41 +0,0 @@ -using UnityEngine; -using UnityEditor; -using System.Diagnostics; -using System.IO; - -namespace SuperSystems.UnityBuild -{ - -public class ScriptRunner : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction -{ - [FilePath(false, true, "Select program/script to run.")] - public string scriptPath = ""; - public string scriptArguments = ""; - - public override void Execute() - { - RunScript(scriptPath, scriptArguments); - } - - public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, System.DateTime buildTime, ref BuildOptions options, string configKey, string buildPath) - { - string resolvedScriptPath = BuildProject.ResolvePath(scriptPath, releaseType, platform, architecture, distribution, buildTime); - string resolvedScriptArgs = BuildProject.ResolvePath(scriptArguments, releaseType, platform, architecture, distribution, buildTime); - - RunScript(resolvedScriptPath, resolvedScriptArgs); - } - - private void RunScript(string scriptPath, string arguments) - { - ProcessStartInfo startInfo = new ProcessStartInfo(); - startInfo.FileName = Path.GetFullPath(scriptPath); - - if (!string.IsNullOrEmpty(arguments)) - startInfo.Arguments = arguments; - - Process proc = Process.Start(startInfo); - proc.WaitForExit(); - } -} - -} diff --git a/UnityBuild-ZipFile/Editor.meta b/UnityBuild-ZipFile/Editor.meta deleted file mode 100644 index a13f38c..0000000 --- a/UnityBuild-ZipFile/Editor.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 5b36d3c7f52545648a445ed554c706e9 -folderAsset: yes -timeCreated: 1483567653 -licenseType: Pro -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityBuild-ZipFile/Editor/ZipFileOperation.cs b/UnityBuild-ZipFile/Editor/ZipFileOperation.cs deleted file mode 100644 index 7b5f0b4..0000000 --- a/UnityBuild-ZipFile/Editor/ZipFileOperation.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Ionic.Zip; -using System; -using System.IO; -using UnityEditor; -using UnityEngine; - -namespace SuperSystems.UnityBuild -{ - -public class ZipFileOperation : BuildAction, IPreBuildAction, IPreBuildPerPlatformAction, IPostBuildAction, IPostBuildPerPlatformAction -{ - public string inputPath = "$BUILDPATH"; - public string outputPath = "$BUILDPATH"; - public string outputFileName = "$PRODUCT_NAME-$RELEASE_TYPE-$YEAR_$MONTH_$DAY.zip"; - - public override void PerBuildExecute(BuildReleaseType releaseType, BuildPlatform platform, BuildArchitecture architecture, BuildDistribution distribution, System.DateTime buildTime, ref UnityEditor.BuildOptions options, string configKey, string buildPath) - { - string resolvedOutputPath = Path.Combine(outputPath.Replace("$BUILDPATH", buildPath), outputFileName); - resolvedOutputPath = BuildProject.ResolvePath(resolvedOutputPath, releaseType, platform, architecture, distribution, buildTime); - - string resolvedInputPath = inputPath.Replace("$BUILDPATH", buildPath); - resolvedInputPath = BuildProject.ResolvePath(resolvedInputPath, releaseType, platform, architecture, distribution, buildTime); - - if (!resolvedOutputPath.EndsWith(".zip")) - resolvedOutputPath += ".zip"; - - PerformZip(Path.GetFullPath(resolvedInputPath), Path.GetFullPath(resolvedOutputPath)); - } - - private void PerformZip(string inputPath, string outputPath) - { - try - { - if (!Directory.Exists(inputPath)) - { - BuildNotificationList.instance.AddNotification(new BuildNotification( - BuildNotification.Category.Error, - "Zip Operation Failed.", string.Format("Input path does not exist: {0}", inputPath), - true, null)); - return; - } - - // Make sure that all parent directories in path are already created. - string parentPath = Path.GetDirectoryName(outputPath); - if (!Directory.Exists(parentPath)) - { - Directory.CreateDirectory(parentPath); - } - - // Delete old file if it exists. - if (File.Exists(outputPath)) - File.Delete(outputPath); - - using (ZipFile zip = new ZipFile(outputPath)) - { - zip.ParallelDeflateThreshold = -1; // Parallel deflate is bugged in DotNetZip, so we need to disable it. - zip.AddDirectory(inputPath); - zip.Save(); - } - } - catch (Exception ex) - { - Debug.LogError(ex.ToString()); - } - } -} - -} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..06a32f8 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "com.github.superunitybuild.buildactions", + "displayName": "SuperUnityBuild BuildActions", + "version": "4.0.1", + "unity": "2020.3", + "description": "BuildActions are one of the key components that make the SuperUnityBuild build automation tool flexible and powerful. Each one extends the capabilities of SuperUnityBuild and can be easily setup and customized to suit your needs", + "changelogUrl": "CHANGELOG.md", + "documentationUrl": "https://github.com/superunitybuild/buildtool/wiki", + "licenseUrl": "LICENSE.md", + "dependencies": { + "com.github.superunitybuild.buildtool": "7.0.0" + }, + "author": { + "name": "SuperUnityBuild", + "url": "https://github.com/superunitybuild" + } +} diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..d58a2c8 --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e009fd4afff97db4f9811f0d88f9d953 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: