Skip to content

Commit

Permalink
Add a bunch of new inputs.
Browse files Browse the repository at this point in the history
  • Loading branch information
ffried committed Mar 28, 2024
1 parent 7d7f812 commit 4d9f5ce
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 46 deletions.
32 changes: 17 additions & 15 deletions .github/dependabot.yml
@@ -1,35 +1,37 @@
version: 2

updates:
- package-ecosystem: "github-actions"
directory: "/"
- package-ecosystem: github-actions
directory: /
open-pull-requests-limit: 10
schedule:
interval: "daily"
time: "07:00"
timezone: "Europe/Berlin"
interval: daily
time: '07:00'
timezone: Europe/Berlin
assignees:
- ffried
reviewers:
- ffried
- package-ecosystem: "github-actions"
directory: ".github/actions/generate-action-code"

- package-ecosystem: github-actions
directory: .github/actions/generate-action-code
open-pull-requests-limit: 10
schedule:
interval: "daily"
time: "07:00"
timezone: "Europe/Berlin"
interval: daily
time: '07:00'
timezone: Europe/Berlin
assignees:
- ffried
reviewers:
- ffried
- package-ecosystem: "npm"
directory: "/"

- package-ecosystem: npm
directory: /
open-pull-requests-limit: 10
schedule:
interval: "daily"
time: "07:00"
timezone: "Europe/Berlin"
interval: daily
time: '07:00'
timezone: Europe/Berlin
assignees:
- ffried
reviewers:
Expand Down
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -11,6 +11,10 @@ Note that this action needs to run on macOS. All other platforms will fail!
See [action.yml](action.yml) for an overview of all inputs.<br/>
For more information about the various inputs, also see `man xcodebuild`.

**Notes:**
- If you are missing an input, you can pass them in the `build-settings` input. These will be passed along to `xcodebuild` as is.
- If an enum input validation fails because you use a value that isn't yet known to this action, set `disable-enum-validation` to `true`.

## Outputs

### `unprocessed-command`
Expand Down
58 changes: 58 additions & 0 deletions action.yml
Expand Up @@ -17,6 +17,9 @@ inputs:
target:
description: The target to build. See also `xcodebuild`'s `-target`.
required: false
all-targets:
description: If `true`, all targets will be built. See also `xcodebuild`'s `-allTargets`.
required: false
destination:
description: The destination specifier to build. See also `xcodebuild`'s `-destination`.
required: false
Expand All @@ -32,6 +35,9 @@ inputs:
xcconfig:
description: The path to an xcconfig file with build settings overrides. See also `xcodebuild`'s `-xcconfig`.
required: false
toolchain:
description: The toolchain identifier or name to use for building. See also `xcodebuild`'s `-toolchain`.
required: false
jobs:
description: The number of jobs to use for building. See also `xcodebuild`'s `-jobs`.
required: false
Expand Down Expand Up @@ -80,6 +86,12 @@ inputs:
derived-data-path:
description: The path that should be used for derived data. See also `xcodebuild`'s `-derivedDataPath`.
required: false
default-package-registry-url:
description: The default package registry URL. See also `xcodebuild`'s `-defaultPackageRegistryURL`.
required: false
package-dependency-scm-to-registry-transformation:
description: The package dependency SCM to registry transformation. See also `xcodebuild`'s `-packageDependencySCMToRegistryTransformation`.
required: false
disable-package-repository-cache:
description: Whether the package repository cache should be disabled. See also `xcodebuild`'s `-disablePackageRepositoryCache`.
required: false
Expand All @@ -95,12 +107,24 @@ inputs:
skip-macro-validation:
description: Whether macro validation should be skipped. See also `xcodebuild`'s `-skipMacroValidation`.
required: false
package-fingerprint-policy:
description: The package fingerprint checking policy. See also `xcodebuild`'s `-packageFingerprintPolicy`.
required: false
package-signing-entity-policy:
description: The package signing entity policy. See also `xcodebuild`'s `-packageSigningEntityPolicy`.
required: false
xcroot:
description: The path to a .xcroot to use for building and/or testing. See also `xcodebuild`'s `-xcroot`.
required: false
xctestrun:
description: The path to a test run specification. See also `xcodebuild`'s `-xctestrun`.
required: false
test-language:
description: The language to use for testing. See also `xcodebuild`'s `-testLanguage`.
required: false
test-region:
description: The region to use for testing. See also `xcodebuild`'s `-testRegion`.
required: false
test-plan:
description: The name of the test plan associated with the scheme to use for testing. See also `xcodebuild`'s `-testPlan`.
required: false
Expand All @@ -110,6 +134,21 @@ inputs:
skip-testing:
description: A (line-separated) list of tests to skip. See also `xcodebuild`'s `-skip-testing`.
required: false
only-test-configuration:
description: A (line-separated) list of test configurations to run. See also `xcodebuild`'s `-only-test-configuration`.
required: false
skip-test-configuration:
description: A (line-separated) list of test configurations to skip. See also `xcodebuild`'s `-skip-test-configuration`.
required: false
test-iterations:
description: The number of iterations to run the tests. See also `xcodebuild`'s `-test-iterations`.
required: false
retry-tests-on-failure:
description: Whether tests should be retried on failure. See also `xcodebuild`'s `-retry-tests-on-failure`.
required: false
run-tests-until-failure:
description: Whether tests should be run until failure. See also `xcodebuild`'s `-run-tests-until-failure`.
required: false
skip-unavailable-actions:
description: Whether unavailable actions should be skipped instead of failing the execution. See also `xcodebuild`'s `-skipUnavailableActions`.
required: false
Expand All @@ -119,6 +158,21 @@ inputs:
allow-provisioning-device-registration:
description: Whether provisioning device registrations are allowed. See also `xcodebuild`'s `-allowProvisioningDeviceRegistration`.
required: false
export-notarized-app:
description: Whether the app should be exported notarized. See also `xcodebuild`'s `-exportNotarizedApp`.
required: false
export-options-plist:
description: The path to an export options plist. See also `xcodebuild`'s `-exportOptionsPlist`.
required: false
export-archive:
description: Whether an archive should be exported. See also `xcodebuild`'s `-exportArchive`.
required: false
archive-path:
description: The path to where archives are created. See also `xcodebuild`'s `-archivePath`.
required: false
create-xcframework:
description: Whether an xcframework should be created. See also `xcodebuild`'s `-create-xcframework`.
required: false
build-settings:
description: Arbitrary, space separated build settings (e.g. PLATFORM_NAME=iphonesimulator).
required: false
Expand All @@ -130,6 +184,10 @@ inputs:
description: The output formatter to use (e.g. xcpretty, xcbeautify, ...). The xcodebuild output will be piped into this formatter.
required: false
default: 'xcpretty --color'
disable-enum-input-validation:
description: Whether the input validation for enums should be disabled. Usually only needed if new values are added to the enums in the future.
required: false
default: 'false'
dry-run:
description: '<TEST ONLY> Whether the commands should only be composed and not actually run. Only used in test.'
required: false
Expand Down
19 changes: 14 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -32,7 +32,7 @@
},
"devDependencies": {
"@tsconfig/node20": "^20.1.4",
"@types/node": "^20.6.2",
"@types/node": "^20.11.30",
"@vercel/ncc": "^0.38.1",
"typescript": "^5.4.3"
}
Expand Down
91 changes: 66 additions & 25 deletions src/main.ts
Expand Up @@ -60,7 +60,7 @@ function argumentValueString(value: ICommandArgumentValue,
function _cmdEscape(str: string): string {
return str.replace(/((?!\\).|^)( )/g, `$1\\ `);
}
let strValue = useResolvedValue ? value.resolvedValue : value.originalValue
let strValue = useResolvedValue ? value.resolvedValue : value.originalValue;
return escapeValue ? _cmdEscape(strValue) : strValue;
}

Expand Down Expand Up @@ -140,6 +140,8 @@ async function main() {
}
const scheme = core.getInput('scheme', { required: !!workspace || !!spmPackage });

const disableEnumInputValidation = core.getBooleanInput('disable-enum-input-validation');

function _pushArg(name: string, value?: ICommandArgumentValue) {
xcodebuildArgs.push({ name: `-${name}`, value: value });
}
Expand All @@ -156,45 +158,64 @@ async function main() {
_pushArg(name, { originalValue: value, resolvedValue: processedValue });
}

function _addInputArg(inputName: string, argName?: string, opts?: { isPath?: boolean, isList?: boolean }) {
if (opts?.isList) {
function _addInputArg(inputName: string,
argName?: string,
opts?: { isPath?: boolean, isList?: boolean, validValues?: string[] }): boolean {
if (opts?.isList) { // opts is guaranteed to be set in this branch.
let values = core.getMultilineInput(inputName);
if (values)
values.forEach(value => _pushArgWithValue(argName ?? inputName, value, {
isPath: opts?.isPath,
if (!values) return false;
for (const value of values) {
if (!disableEnumInputValidation && opts.validValues && !opts.validValues.includes(value))
throw new Error(`Invalid value for ${inputName}: ${value}! Valid values: ${opts.validValues.join(', ')}`);
_pushArgWithValue(argName ?? inputName, value, {
isPath: opts.isPath,
skipEmptyValues: true,
}));
});
}
return values.length > 0;
} else {
let value = core.getInput(inputName);
if (value)
_pushArgWithValue(argName ?? inputName, value, {
isPath: opts?.isPath,
skipEmptyValues: false,
})
if (!value) return false;
if (!disableEnumInputValidation && opts?.validValues && !opts.validValues.includes(value))
throw new Error(`Invalid value for ${inputName}: ${value}! Valid values: ${opts.validValues.join(', ')}`);
_pushArgWithValue(argName ?? inputName, value, {
isPath: opts?.isPath,
skipEmptyValues: false,
});
return true;
}
}

function addInputArg(inputName: string, argName?: string) {
_addInputArg(inputName, argName);
function addInputArg(inputName: string, argName?: string): boolean {
return _addInputArg(inputName, argName);
}

function addPathArg(inputName: string, argName?: string) {
_addInputArg(inputName, argName, { isPath: true });
function addPathArg(inputName: string, argName?: string): boolean {
return _addInputArg(inputName, argName, { isPath: true });
}

function addListArg(inputName: string, argName?: string) {
_addInputArg(inputName, argName, { isList: true });
function addListArg(inputName: string, argName?: string): boolean {
return _addInputArg(inputName, argName, { isList: true });
}

function addBoolArg(inputName: string, argName?: string) {
function addEnumArg(inputName: string, validValues: string[], argName?: string): boolean {
return _addInputArg(inputName, argName, { validValues });
}

function addBoolArg(inputName: string, argName?: string): boolean {
const value = core.getInput(inputName);
if (value?.length)
_pushArgWithValue(argName ?? inputName, core.getBooleanInput(inputName) ? 'YES' : 'NO')
const hasValue = !!value && value.length > 0;
if (hasValue)
_pushArgWithValue(argName ?? inputName, core.getBooleanInput(inputName) ? 'YES' : 'NO');
return hasValue;
}

function addFlagArg(inputName: string, argName?: string) {
if (core.getInput(inputName).length && core.getBooleanInput(inputName))
function addFlagArg(inputName: string, argName?: string): boolean {
const value = core.getInput(inputName);
const hasValue = !!value && value.length > 0;
if (hasValue && core.getBooleanInput(inputName))
_pushArg(argName ?? inputName);
return hasValue;
}

if (workspace) {
Expand All @@ -204,12 +225,14 @@ async function main() {
}
if (scheme) _pushArgWithValue('scheme', scheme);

addInputArg('target');
if (addInputArg('target') && addFlagArg('all-targets', 'alltargets'))
throw new Error('`target` and `all-targets` are mutually exclusive!');
addInputArg('destination');
addInputArg('configuration');
addInputArg('sdk');
addInputArg('arch');
addPathArg('xcconfig');
addInputArg('toolchain');
addInputArg('jobs');
addFlagArg('parallelize-targets', 'parallelizeTargets');
addBoolArg('enable-code-coverage', 'enableCodeCoverage');
Expand All @@ -226,19 +249,37 @@ async function main() {
addPathArg('cloned-source-packages-path', 'clonedSourcePackagesDirPath');
addPathArg('package-cache-path', 'packageCachePath');
addPathArg('derived-data-path', 'derivedDataPath');
addInputArg('default-package-registry-url', 'defaultPackageRegistryURL');
addEnumArg('package-dependency-scm-to-registry-transformation',
['none', 'useRegistryIdentity', 'useRegistryIdentityAndSources'],
'packageDependencySCMToRegistryTransformation');
addFlagArg('disable-package-repository-cache', 'disablePackageRepositoryCache');
addFlagArg('disable-automatic-package-resolution', 'disableAutomaticPackageResolution');
addFlagArg('skip-package-updates', 'skipPackageUpdates');
addFlagArg('skip-package-plugin-validation', 'skipPackagePluginValidation');
addFlagArg('skip-macro-validation', 'skipMacroValidation');
addEnumArg('package-fingerprint-policy', ['warn', 'strict'], 'packageFingerprintPolicy');
addEnumArg('package-signing-entity-policy', ['warn', 'strict'], 'packageSigningEntityPolicy');
addPathArg('xcroot');
addPathArg('xctestrun');
addInputArg('test-language', 'testLanguage');
addInputArg('test-region', 'testRegion');
addInputArg('test-plan', 'testPlan');
addListArg('only-testing');
addListArg('skip-testing');
addListArg('only-test-configuration');
addListArg('skip-test-configuration');
addInputArg('test-iterations');
addFlagArg('retry-tests-on-failure');
addFlagArg('run-tests-until-failure');
addFlagArg('skip-unavailable-actions', 'skipUnavailableActions');
addFlagArg('allow-provisioning-updates', 'allowProvisioningUpdates');
addFlagArg('allow-provisioning-device-registration', 'allowProvisioningDeviceRegistration');
addFlagArg('export-notarized-app', 'exportNotarizedApp');
addPathArg('export-options-plist', 'exportOptionsPlist');
addFlagArg('export-archive', 'exportArchive');
addPathArg('archive-path', 'archivePath');
addFlagArg('create-xcframework');

const buildSettings = core.getInput('build-settings');
if (buildSettings)
Expand Down Expand Up @@ -285,7 +326,7 @@ async function main() {
...inv,
';',
'popd',
]
];
}
unprocessedInvocation = _combinedInv(unprocessedInvocation, false);
processedInvocation = _combinedInv(processedInvocation, true);
Expand Down

0 comments on commit 4d9f5ce

Please sign in to comment.