@invarn/cibuild 1.3.16 → 1.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/dist/cli.cjs +1 -1
  2. package/dist/src/cli.d.ts +3 -0
  3. package/dist/src/cli.d.ts.map +1 -0
  4. package/dist/src/cli.js +987 -0
  5. package/dist/src/commands/android-scanner.d.ts +32 -0
  6. package/dist/src/commands/android-scanner.d.ts.map +1 -0
  7. package/dist/src/commands/android-scanner.js +667 -0
  8. package/dist/src/commands/build.d.ts +5 -0
  9. package/dist/src/commands/build.d.ts.map +1 -0
  10. package/dist/src/commands/build.js +1096 -0
  11. package/dist/src/commands/edit.d.ts +3 -0
  12. package/dist/src/commands/edit.d.ts.map +1 -0
  13. package/dist/src/commands/edit.js +651 -0
  14. package/dist/src/commands/file-secret-collector.d.ts +37 -0
  15. package/dist/src/commands/file-secret-collector.d.ts.map +1 -0
  16. package/dist/src/commands/file-secret-collector.js +199 -0
  17. package/dist/src/commands/github-workflow.d.ts +5 -0
  18. package/dist/src/commands/github-workflow.d.ts.map +1 -0
  19. package/dist/src/commands/github-workflow.js +45 -0
  20. package/dist/src/commands/ios-scanner.d.ts +27 -0
  21. package/dist/src/commands/ios-scanner.d.ts.map +1 -0
  22. package/dist/src/commands/ios-scanner.js +337 -0
  23. package/dist/src/commands/reset.d.ts +7 -0
  24. package/dist/src/commands/reset.d.ts.map +1 -0
  25. package/dist/src/commands/reset.js +81 -0
  26. package/dist/src/commands/secrets-sync-workflow.d.ts +15 -0
  27. package/dist/src/commands/secrets-sync-workflow.d.ts.map +1 -0
  28. package/dist/src/commands/secrets-sync-workflow.js +255 -0
  29. package/dist/src/commands/secrets-upload.d.ts +21 -0
  30. package/dist/src/commands/secrets-upload.d.ts.map +1 -0
  31. package/dist/src/commands/secrets-upload.js +177 -0
  32. package/dist/src/commands/secrets-upload.test.d.ts +5 -0
  33. package/dist/src/commands/secrets-upload.test.d.ts.map +1 -0
  34. package/dist/src/commands/secrets-upload.test.js +60 -0
  35. package/dist/src/config.d.ts +3 -0
  36. package/dist/src/config.d.ts.map +1 -0
  37. package/dist/src/config.js +47 -0
  38. package/dist/src/envman/cli.d.ts +21 -0
  39. package/dist/src/envman/cli.d.ts.map +1 -0
  40. package/dist/src/envman/cli.js +240 -0
  41. package/dist/src/envman/envman.d.ts +83 -0
  42. package/dist/src/envman/envman.d.ts.map +1 -0
  43. package/dist/src/envman/envman.js +361 -0
  44. package/dist/src/envman/envman.test.d.ts +5 -0
  45. package/dist/src/envman/envman.test.d.ts.map +1 -0
  46. package/dist/src/envman/envman.test.js +236 -0
  47. package/dist/src/envman/index.d.ts +23 -0
  48. package/dist/src/envman/index.d.ts.map +1 -0
  49. package/dist/src/envman/index.js +23 -0
  50. package/dist/src/envman/types.d.ts +55 -0
  51. package/dist/src/envman/types.d.ts.map +1 -0
  52. package/dist/src/envman/types.js +12 -0
  53. package/dist/src/lib.d.ts +27 -0
  54. package/dist/src/lib.d.ts.map +1 -0
  55. package/dist/src/lib.js +32 -0
  56. package/dist/src/pipeline.d.ts +3 -0
  57. package/dist/src/pipeline.d.ts.map +1 -0
  58. package/dist/src/pipeline.js +57 -0
  59. package/dist/src/runner.d.ts +17 -0
  60. package/dist/src/runner.d.ts.map +1 -0
  61. package/dist/src/runner.js +234 -0
  62. package/dist/src/types.d.ts +58 -0
  63. package/dist/src/types.d.ts.map +1 -0
  64. package/dist/src/types.js +2 -0
  65. package/dist/src/yaml/bitrise-compat.d.ts +65 -0
  66. package/dist/src/yaml/bitrise-compat.d.ts.map +1 -0
  67. package/dist/src/yaml/bitrise-compat.js +206 -0
  68. package/dist/src/yaml/bitrise-compat.test.d.ts +5 -0
  69. package/dist/src/yaml/bitrise-compat.test.d.ts.map +1 -0
  70. package/dist/src/yaml/bitrise-compat.test.js +347 -0
  71. package/dist/src/yaml/converter.d.ts +33 -0
  72. package/dist/src/yaml/converter.d.ts.map +1 -0
  73. package/dist/src/yaml/converter.js +222 -0
  74. package/dist/src/yaml/converter.test.d.ts +5 -0
  75. package/dist/src/yaml/converter.test.d.ts.map +1 -0
  76. package/dist/src/yaml/converter.test.js +348 -0
  77. package/dist/src/yaml/e2e.test.d.ts +6 -0
  78. package/dist/src/yaml/e2e.test.d.ts.map +1 -0
  79. package/dist/src/yaml/e2e.test.js +446 -0
  80. package/dist/src/yaml/env-resolver.d.ts +120 -0
  81. package/dist/src/yaml/env-resolver.d.ts.map +1 -0
  82. package/dist/src/yaml/env-resolver.js +405 -0
  83. package/dist/src/yaml/env-resolver.test.d.ts +5 -0
  84. package/dist/src/yaml/env-resolver.test.d.ts.map +1 -0
  85. package/dist/src/yaml/env-resolver.test.js +502 -0
  86. package/dist/src/yaml/interactive-prompts.d.ts +71 -0
  87. package/dist/src/yaml/interactive-prompts.d.ts.map +1 -0
  88. package/dist/src/yaml/interactive-prompts.js +258 -0
  89. package/dist/src/yaml/missing-env-handler.d.ts +45 -0
  90. package/dist/src/yaml/missing-env-handler.d.ts.map +1 -0
  91. package/dist/src/yaml/missing-env-handler.js +64 -0
  92. package/dist/src/yaml/parser.d.ts +33 -0
  93. package/dist/src/yaml/parser.d.ts.map +1 -0
  94. package/dist/src/yaml/parser.js +145 -0
  95. package/dist/src/yaml/pipeline-with-secrets.d.ts +25 -0
  96. package/dist/src/yaml/pipeline-with-secrets.d.ts.map +1 -0
  97. package/dist/src/yaml/pipeline-with-secrets.js +76 -0
  98. package/dist/src/yaml/platform-detector.d.ts +83 -0
  99. package/dist/src/yaml/platform-detector.d.ts.map +1 -0
  100. package/dist/src/yaml/platform-detector.js +188 -0
  101. package/dist/src/yaml/platform-detector.test.d.ts +5 -0
  102. package/dist/src/yaml/platform-detector.test.d.ts.map +1 -0
  103. package/dist/src/yaml/platform-detector.test.js +414 -0
  104. package/dist/src/yaml/preflight-validation.d.ts +40 -0
  105. package/dist/src/yaml/preflight-validation.d.ts.map +1 -0
  106. package/dist/src/yaml/preflight-validation.js +152 -0
  107. package/dist/src/yaml/secrets-manager.d.ts +77 -0
  108. package/dist/src/yaml/secrets-manager.d.ts.map +1 -0
  109. package/dist/src/yaml/secrets-manager.js +219 -0
  110. package/dist/src/yaml/step-validator.d.ts +54 -0
  111. package/dist/src/yaml/step-validator.d.ts.map +1 -0
  112. package/dist/src/yaml/step-validator.js +403 -0
  113. package/dist/src/yaml/steps/android-sign.d.ts +35 -0
  114. package/dist/src/yaml/steps/android-sign.d.ts.map +1 -0
  115. package/dist/src/yaml/steps/android-sign.js +147 -0
  116. package/dist/src/yaml/steps/android-version.d.ts +26 -0
  117. package/dist/src/yaml/steps/android-version.d.ts.map +1 -0
  118. package/dist/src/yaml/steps/android-version.js +128 -0
  119. package/dist/src/yaml/steps/android-version.test.d.ts +5 -0
  120. package/dist/src/yaml/steps/android-version.test.d.ts.map +1 -0
  121. package/dist/src/yaml/steps/android-version.test.js +196 -0
  122. package/dist/src/yaml/steps/android.d.ts +95 -0
  123. package/dist/src/yaml/steps/android.d.ts.map +1 -0
  124. package/dist/src/yaml/steps/android.js +916 -0
  125. package/dist/src/yaml/steps/app-store-deploy.d.ts +48 -0
  126. package/dist/src/yaml/steps/app-store-deploy.d.ts.map +1 -0
  127. package/dist/src/yaml/steps/app-store-deploy.js +162 -0
  128. package/dist/src/yaml/steps/base.d.ts +238 -0
  129. package/dist/src/yaml/steps/base.d.ts.map +1 -0
  130. package/dist/src/yaml/steps/base.js +345 -0
  131. package/dist/src/yaml/steps/bitrise-android-tools.d.ts +26 -0
  132. package/dist/src/yaml/steps/bitrise-android-tools.d.ts.map +1 -0
  133. package/dist/src/yaml/steps/bitrise-android-tools.js +198 -0
  134. package/dist/src/yaml/steps/bitrise-android-tools.test.d.ts +5 -0
  135. package/dist/src/yaml/steps/bitrise-android-tools.test.d.ts.map +1 -0
  136. package/dist/src/yaml/steps/bitrise-android-tools.test.js +280 -0
  137. package/dist/src/yaml/steps/bitrise-apk-info.d.ts +22 -0
  138. package/dist/src/yaml/steps/bitrise-apk-info.d.ts.map +1 -0
  139. package/dist/src/yaml/steps/bitrise-apk-info.js +144 -0
  140. package/dist/src/yaml/steps/bitrise-apk-info.test.d.ts +5 -0
  141. package/dist/src/yaml/steps/bitrise-apk-info.test.d.ts.map +1 -0
  142. package/dist/src/yaml/steps/bitrise-apk-info.test.js +331 -0
  143. package/dist/src/yaml/steps/bitrise-slack.d.ts +49 -0
  144. package/dist/src/yaml/steps/bitrise-slack.d.ts.map +1 -0
  145. package/dist/src/yaml/steps/bitrise-slack.js +280 -0
  146. package/dist/src/yaml/steps/bitrise-slack.test.d.ts +5 -0
  147. package/dist/src/yaml/steps/bitrise-slack.test.d.ts.map +1 -0
  148. package/dist/src/yaml/steps/bitrise-slack.test.js +484 -0
  149. package/dist/src/yaml/steps/bitrise-ssh.d.ts +27 -0
  150. package/dist/src/yaml/steps/bitrise-ssh.d.ts.map +1 -0
  151. package/dist/src/yaml/steps/bitrise-ssh.js +134 -0
  152. package/dist/src/yaml/steps/bitrise-ssh.test.d.ts +5 -0
  153. package/dist/src/yaml/steps/bitrise-ssh.test.d.ts.map +1 -0
  154. package/dist/src/yaml/steps/bitrise-ssh.test.js +205 -0
  155. package/dist/src/yaml/steps/cache.d.ts +52 -0
  156. package/dist/src/yaml/steps/cache.d.ts.map +1 -0
  157. package/dist/src/yaml/steps/cache.js +352 -0
  158. package/dist/src/yaml/steps/fastlane.d.ts +27 -0
  159. package/dist/src/yaml/steps/fastlane.d.ts.map +1 -0
  160. package/dist/src/yaml/steps/fastlane.js +79 -0
  161. package/dist/src/yaml/steps/file.d.ts +27 -0
  162. package/dist/src/yaml/steps/file.d.ts.map +1 -0
  163. package/dist/src/yaml/steps/file.js +35 -0
  164. package/dist/src/yaml/steps/flutter.d.ts +63 -0
  165. package/dist/src/yaml/steps/flutter.d.ts.map +1 -0
  166. package/dist/src/yaml/steps/flutter.js +215 -0
  167. package/dist/src/yaml/steps/git-clone.d.ts +26 -0
  168. package/dist/src/yaml/steps/git-clone.d.ts.map +1 -0
  169. package/dist/src/yaml/steps/git-clone.js +111 -0
  170. package/dist/src/yaml/steps/google-play-deploy.d.ts +37 -0
  171. package/dist/src/yaml/steps/google-play-deploy.d.ts.map +1 -0
  172. package/dist/src/yaml/steps/google-play-deploy.js +193 -0
  173. package/dist/src/yaml/steps/google-play-deploy.test.d.ts +5 -0
  174. package/dist/src/yaml/steps/google-play-deploy.test.d.ts.map +1 -0
  175. package/dist/src/yaml/steps/google-play-deploy.test.js +310 -0
  176. package/dist/src/yaml/steps/index.d.ts +10 -0
  177. package/dist/src/yaml/steps/index.d.ts.map +1 -0
  178. package/dist/src/yaml/steps/index.js +1361 -0
  179. package/dist/src/yaml/steps/ios-deps.d.ts +43 -0
  180. package/dist/src/yaml/steps/ios-deps.d.ts.map +1 -0
  181. package/dist/src/yaml/steps/ios-deps.js +141 -0
  182. package/dist/src/yaml/steps/ios-deps.test.d.ts +5 -0
  183. package/dist/src/yaml/steps/ios-deps.test.d.ts.map +1 -0
  184. package/dist/src/yaml/steps/ios-deps.test.js +90 -0
  185. package/dist/src/yaml/steps/ios-signing.d.ts +31 -0
  186. package/dist/src/yaml/steps/ios-signing.d.ts.map +1 -0
  187. package/dist/src/yaml/steps/ios-signing.js +144 -0
  188. package/dist/src/yaml/steps/ios-version.d.ts +47 -0
  189. package/dist/src/yaml/steps/ios-version.d.ts.map +1 -0
  190. package/dist/src/yaml/steps/ios-version.js +151 -0
  191. package/dist/src/yaml/steps/linting.d.ts +47 -0
  192. package/dist/src/yaml/steps/linting.d.ts.map +1 -0
  193. package/dist/src/yaml/steps/linting.js +148 -0
  194. package/dist/src/yaml/steps/phase2.test.d.ts +6 -0
  195. package/dist/src/yaml/steps/phase2.test.d.ts.map +1 -0
  196. package/dist/src/yaml/steps/phase2.test.js +197 -0
  197. package/dist/src/yaml/steps/phase3.test.d.ts +5 -0
  198. package/dist/src/yaml/steps/phase3.test.d.ts.map +1 -0
  199. package/dist/src/yaml/steps/phase3.test.js +144 -0
  200. package/dist/src/yaml/steps/phase4.test.d.ts +5 -0
  201. package/dist/src/yaml/steps/phase4.test.d.ts.map +1 -0
  202. package/dist/src/yaml/steps/phase4.test.js +166 -0
  203. package/dist/src/yaml/steps/phase5.test.d.ts +6 -0
  204. package/dist/src/yaml/steps/phase5.test.d.ts.map +1 -0
  205. package/dist/src/yaml/steps/phase5.test.js +263 -0
  206. package/dist/src/yaml/steps/registry.d.ts +88 -0
  207. package/dist/src/yaml/steps/registry.d.ts.map +1 -0
  208. package/dist/src/yaml/steps/registry.js +125 -0
  209. package/dist/src/yaml/steps/registry.test.d.ts +5 -0
  210. package/dist/src/yaml/steps/registry.test.d.ts.map +1 -0
  211. package/dist/src/yaml/steps/registry.test.js +235 -0
  212. package/dist/src/yaml/steps/release.d.ts +50 -0
  213. package/dist/src/yaml/steps/release.d.ts.map +1 -0
  214. package/dist/src/yaml/steps/release.js +154 -0
  215. package/dist/src/yaml/steps/script.d.ts +23 -0
  216. package/dist/src/yaml/steps/script.d.ts.map +1 -0
  217. package/dist/src/yaml/steps/script.js +63 -0
  218. package/dist/src/yaml/steps/spec-validation.test.d.ts +6 -0
  219. package/dist/src/yaml/steps/spec-validation.test.d.ts.map +1 -0
  220. package/dist/src/yaml/steps/spec-validation.test.js +130 -0
  221. package/dist/src/yaml/steps/steps.test.d.ts +6 -0
  222. package/dist/src/yaml/steps/steps.test.d.ts.map +1 -0
  223. package/dist/src/yaml/steps/steps.test.js +505 -0
  224. package/dist/src/yaml/steps/test-config.d.ts +3 -0
  225. package/dist/src/yaml/steps/test-config.d.ts.map +1 -0
  226. package/dist/src/yaml/steps/test-config.js +17 -0
  227. package/dist/src/yaml/steps/xcode-new.test.d.ts +5 -0
  228. package/dist/src/yaml/steps/xcode-new.test.d.ts.map +1 -0
  229. package/dist/src/yaml/steps/xcode-new.test.js +211 -0
  230. package/dist/src/yaml/steps/xcode.d.ts +222 -0
  231. package/dist/src/yaml/steps/xcode.d.ts.map +1 -0
  232. package/dist/src/yaml/steps/xcode.js +999 -0
  233. package/dist/src/yaml/types.d.ts +68 -0
  234. package/dist/src/yaml/types.d.ts.map +1 -0
  235. package/dist/src/yaml/types.js +5 -0
  236. package/dist/src/yaml/validation-types.d.ts +96 -0
  237. package/dist/src/yaml/validation-types.d.ts.map +1 -0
  238. package/dist/src/yaml/validation-types.js +8 -0
  239. package/dist/src/yaml/yaml-updater.d.ts +24 -0
  240. package/dist/src/yaml/yaml-updater.d.ts.map +1 -0
  241. package/dist/src/yaml/yaml-updater.js +128 -0
  242. package/package.json +16 -4
@@ -0,0 +1,403 @@
1
+ /**
2
+ * Pre-execution validation orchestrator
3
+ *
4
+ * Validates all steps in a workflow BEFORE execution begins.
5
+ * All validation checks are READ-ONLY and safe to run on the user's machine.
6
+ * This enables catching all issues at once instead of failing on the first error.
7
+ */
8
+ import { getStepExecutor, hasStep, getStepMetadata } from './steps/registry.js';
9
+ import { EnvResolver } from './env-resolver.js';
10
+ import { detectPlatformInfo } from './platform-detector.js';
11
+ // POSIX env vars the shell always provides — don't flag these as undeclared.
12
+ // The runner's guest shell seeds HOME, TMPDIR, PATH, etc.; requiring
13
+ // pipelines to redeclare them forces literal-path-only scripts.
14
+ const POSIX_ENV_ALLOWLIST = new Set([
15
+ 'HOME',
16
+ 'USER',
17
+ 'PATH',
18
+ 'TMPDIR',
19
+ 'TMP',
20
+ 'TEMP',
21
+ 'SHELL',
22
+ 'LANG',
23
+ 'LC_ALL',
24
+ 'PWD',
25
+ 'LOGNAME',
26
+ 'HOSTNAME',
27
+ ]);
28
+ /**
29
+ * StepValidator orchestrates pre-execution validation for a workflow.
30
+ * It iterates through all steps, collects validation requirements,
31
+ * runs pre-execution checks, and aggregates all issues.
32
+ */
33
+ export class StepValidator {
34
+ pipeline;
35
+ workflow;
36
+ workflowName;
37
+ config;
38
+ envResolver;
39
+ yamlFilePath;
40
+ // Track outputs provided by earlier steps for dependency validation
41
+ availableOutputs = new Map();
42
+ // Platform established by the first platform-specific step ('ios' or 'android')
43
+ establishedPlatform = null;
44
+ constructor(pipeline, workflowName, config, yamlFilePath) {
45
+ this.pipeline = pipeline;
46
+ this.workflowName = workflowName;
47
+ this.workflow = pipeline.workflows[workflowName];
48
+ this.config = config;
49
+ this.yamlFilePath = yamlFilePath;
50
+ if (!this.workflow) {
51
+ throw new Error(`Workflow '${workflowName}' not found in pipeline`);
52
+ }
53
+ // Create env resolver for variable interpolation
54
+ const platformInfo = detectPlatformInfo(pipeline, workflowName);
55
+ this.envResolver = new EnvResolver(pipeline, this.workflow, workflowName, platformInfo.platform, platformInfo.stack, yamlFilePath);
56
+ }
57
+ /**
58
+ * Validates all steps in the workflow.
59
+ * Returns a complete validation result with all issues grouped by step and category.
60
+ */
61
+ async validateWorkflow() {
62
+ const issues = [];
63
+ const issuesByStep = new Map();
64
+ const issuesByCategory = new Map();
65
+ let stepIndex = 0;
66
+ for (const yamlStep of this.workflow.steps) {
67
+ const parsedStep = this.parseStep(yamlStep, stepIndex);
68
+ // Skip unrecognized steps (they'll be handled by converter with warnings)
69
+ if (!hasStep(parsedStep.name)) {
70
+ stepIndex++;
71
+ continue;
72
+ }
73
+ const executor = getStepExecutor(parsedStep.name);
74
+ // Platform compatibility check
75
+ const stepMetadata = getStepMetadata(parsedStep.name);
76
+ const stepPlatform = stepMetadata?.platform ?? 'all';
77
+ if (stepPlatform !== 'all') {
78
+ if (this.establishedPlatform === null) {
79
+ // First platform-specific step establishes the workflow platform
80
+ this.establishedPlatform = stepPlatform;
81
+ }
82
+ else if (this.establishedPlatform !== stepPlatform) {
83
+ // This step conflicts with the established platform
84
+ const platformIssue = {
85
+ stepName: parsedStep.title || parsedStep.name,
86
+ stepIndex,
87
+ requirement: {
88
+ category: 'platform',
89
+ name: parsedStep.name,
90
+ description: `'${parsedStep.name}' is an ${stepPlatform} step but this workflow targets ${this.establishedPlatform}`,
91
+ timing: 'pre-execution',
92
+ severity: 'error',
93
+ hint: `Remove this step or move it to a dedicated ${stepPlatform} workflow`,
94
+ check: async () => ({
95
+ passed: false,
96
+ message: `Cross-platform step: '${parsedStep.name}' (${stepPlatform}) cannot be used in an ${this.establishedPlatform} workflow`,
97
+ }),
98
+ },
99
+ result: {
100
+ passed: false,
101
+ message: `Cross-platform step: '${parsedStep.name}' (${stepPlatform}) cannot be used in an ${this.establishedPlatform} workflow`,
102
+ },
103
+ };
104
+ issues.push(platformIssue);
105
+ const stepIssues = issuesByStep.get(platformIssue.stepName) || [];
106
+ stepIssues.push(platformIssue);
107
+ issuesByStep.set(platformIssue.stepName, stepIssues);
108
+ const catIssues = issuesByCategory.get('platform') || [];
109
+ catIssues.push(platformIssue);
110
+ issuesByCategory.set('platform', catIssues);
111
+ stepIndex++;
112
+ continue;
113
+ }
114
+ }
115
+ // Skip all validation for steps that will be skipped in local mode
116
+ if (this.config.local && executor.isSkippedInLocalMode?.()) {
117
+ if (executor.getOutputs) {
118
+ for (const output of executor.getOutputs()) {
119
+ this.availableOutputs.set(output.name, { stepName: parsedStep.name, output });
120
+ }
121
+ }
122
+ stepIndex++;
123
+ continue;
124
+ }
125
+ // Get validation requirements if the executor supports it
126
+ if (executor.getValidationRequirements) {
127
+ // Interpolate inputs (but don't throw on missing vars during validation)
128
+ let interpolatedInputs = parsedStep.inputs;
129
+ try {
130
+ interpolatedInputs = this.envResolver.interpolateObject(parsedStep.inputs, parsedStep.title || parsedStep.name);
131
+ }
132
+ catch {
133
+ // Interpolation failed because a variable isn't set yet.
134
+ // Use a lenient copy: strip unresolved $VAR / ${VAR} references to ''
135
+ // so getValidationRequirements can correctly detect them as missing.
136
+ interpolatedInputs = this.stripUnresolvedVars(parsedStep.inputs);
137
+ }
138
+ const requirements = executor.getValidationRequirements(interpolatedInputs, this.envResolver.getAll(), this.config);
139
+ // Validate each requirement
140
+ for (const req of requirements) {
141
+ const issue = await this.validateRequirement(req, parsedStep.title || parsedStep.name, stepIndex);
142
+ if (issue) {
143
+ issues.push(issue);
144
+ // Group by step
145
+ const stepIssues = issuesByStep.get(issue.stepName) || [];
146
+ stepIssues.push(issue);
147
+ issuesByStep.set(issue.stepName, stepIssues);
148
+ // Group by category
149
+ const catIssues = issuesByCategory.get(issue.requirement.category) || [];
150
+ catIssues.push(issue);
151
+ issuesByCategory.set(issue.requirement.category, catIssues);
152
+ }
153
+ }
154
+ // Auto-discover any $VAR references in raw inputs that aren't covered above
155
+ const resolvedEnv = this.envResolver.getAll();
156
+ const alreadyDeclared = new Set(requirements.map((r) => r.name));
157
+ const referencedVars = this.extractVariableReferences(parsedStep.inputs);
158
+ for (const varName of referencedVars) {
159
+ // Skip POSIX vars the shell always provides
160
+ if (POSIX_ENV_ALLOWLIST.has(varName))
161
+ continue;
162
+ // Skip if already in resolved env (use hasOwnProperty so empty-string
163
+ // values set by the YAML/secrets are still treated as "provided")
164
+ if (Object.prototype.hasOwnProperty.call(resolvedEnv, varName))
165
+ continue;
166
+ // Skip if provided as output by an earlier step
167
+ if (this.availableOutputs.has(varName))
168
+ continue;
169
+ // Skip if already declared by getValidationRequirements
170
+ if (alreadyDeclared.has(varName))
171
+ continue;
172
+ // Skip if already added by a previous step
173
+ if (issues.some((i) => i.requirement.name === varName))
174
+ continue;
175
+ // Skippable steps won't block the build if they fail — downgrade to warning
176
+ // so missing vars don't prevent the run when the step can safely be skipped.
177
+ const severity = parsedStep.is_skippable ? 'warning' : 'error';
178
+ const req = {
179
+ category: 'environment',
180
+ name: varName,
181
+ description: `${varName} is not set`,
182
+ timing: 'pre-execution',
183
+ severity,
184
+ check: async () => ({ passed: false, message: `${varName} is not set` }),
185
+ };
186
+ const issue = await this.validateRequirement(req, parsedStep.title || parsedStep.name, stepIndex);
187
+ if (issue) {
188
+ issues.push(issue);
189
+ const stepIssues = issuesByStep.get(issue.stepName) || [];
190
+ stepIssues.push(issue);
191
+ issuesByStep.set(issue.stepName, stepIssues);
192
+ const catIssues = issuesByCategory.get(issue.requirement.category) || [];
193
+ catIssues.push(issue);
194
+ issuesByCategory.set(issue.requirement.category, catIssues);
195
+ }
196
+ }
197
+ }
198
+ // Record outputs this step provides for later steps
199
+ if (executor.getOutputs) {
200
+ for (const output of executor.getOutputs()) {
201
+ this.availableOutputs.set(output.name, {
202
+ stepName: parsedStep.name,
203
+ output,
204
+ });
205
+ }
206
+ }
207
+ stepIndex++;
208
+ }
209
+ // Count issues by severity
210
+ const counts = {
211
+ errors: issues.filter((i) => i.requirement.severity === 'error').length,
212
+ warnings: issues.filter((i) => i.requirement.severity === 'warning').length,
213
+ info: issues.filter((i) => i.requirement.severity === 'info').length,
214
+ };
215
+ return {
216
+ valid: counts.errors === 0,
217
+ issues,
218
+ issuesByStep,
219
+ issuesByCategory,
220
+ counts,
221
+ };
222
+ }
223
+ /**
224
+ * Validates a single requirement and returns an issue if it fails
225
+ */
226
+ async validateRequirement(requirement, stepName, stepIndex) {
227
+ // Skip runtime-only checks (they can't be validated before execution)
228
+ if (requirement.timing === 'runtime') {
229
+ // For runtime dependencies, check if the providing step exists earlier
230
+ if (requirement.providedBy) {
231
+ const provider = this.availableOutputs.get(requirement.name);
232
+ if (!provider) {
233
+ // Output not provided by any earlier step - this is an info message
234
+ return {
235
+ stepName,
236
+ stepIndex,
237
+ requirement,
238
+ result: {
239
+ passed: false,
240
+ message: `'${requirement.name}' will be provided by '${requirement.providedBy}' step at runtime`,
241
+ },
242
+ };
243
+ }
244
+ }
245
+ return null; // Skip other runtime checks
246
+ }
247
+ // Run the check if available
248
+ if (requirement.check) {
249
+ try {
250
+ const result = await requirement.check();
251
+ if (!result.passed) {
252
+ return {
253
+ stepName,
254
+ stepIndex,
255
+ requirement,
256
+ result,
257
+ };
258
+ }
259
+ }
260
+ catch (error) {
261
+ return {
262
+ stepName,
263
+ stepIndex,
264
+ requirement,
265
+ result: {
266
+ passed: false,
267
+ message: `Check failed: ${error instanceof Error ? error.message : String(error)}`,
268
+ },
269
+ };
270
+ }
271
+ }
272
+ return null;
273
+ }
274
+ /**
275
+ * Extracts all $VAR and ${VAR} variable names referenced in an object recursively.
276
+ */
277
+ extractVariableReferences(obj) {
278
+ const vars = new Set();
279
+ if (typeof obj === 'string') {
280
+ const pattern = /\$\{([^}]+)\}|\$([A-Z_][A-Z_0-9]*)/g;
281
+ let match;
282
+ while ((match = pattern.exec(obj)) !== null) {
283
+ vars.add(match[1] || match[2]);
284
+ }
285
+ }
286
+ else if (Array.isArray(obj)) {
287
+ for (const item of obj) {
288
+ for (const v of this.extractVariableReferences(item))
289
+ vars.add(v);
290
+ }
291
+ }
292
+ else if (obj && typeof obj === 'object') {
293
+ for (const value of Object.values(obj)) {
294
+ for (const v of this.extractVariableReferences(value))
295
+ vars.add(v);
296
+ }
297
+ }
298
+ return vars;
299
+ }
300
+ /**
301
+ * Replaces all unresolved $VAR and ${VAR} references with empty string.
302
+ * Used as a lenient fallback when full interpolation fails, so that
303
+ * getValidationRequirements can detect truly-missing variables correctly.
304
+ */
305
+ stripUnresolvedVars(obj) {
306
+ if (typeof obj === 'string') {
307
+ return obj.replace(/\$\{[^}]+\}|\$[A-Z_][A-Z_0-9]*/g, '');
308
+ }
309
+ if (Array.isArray(obj)) {
310
+ return obj.map((item) => this.stripUnresolvedVars(item));
311
+ }
312
+ if (obj && typeof obj === 'object') {
313
+ const result = {};
314
+ for (const [key, value] of Object.entries(obj)) {
315
+ result[key] = this.stripUnresolvedVars(value);
316
+ }
317
+ return result;
318
+ }
319
+ return obj;
320
+ }
321
+ /**
322
+ * Parses a YAML step into a ParsedStep (simplified version of converter logic)
323
+ */
324
+ parseStep(yamlStep, _index) {
325
+ const stepKeys = Object.keys(yamlStep);
326
+ const stepNameWithVersion = stepKeys[0];
327
+ const stepConfig = yamlStep[stepNameWithVersion];
328
+ const atIndex = stepNameWithVersion.indexOf('@');
329
+ const name = atIndex === -1 ? stepNameWithVersion : stepNameWithVersion.substring(0, atIndex);
330
+ const version = atIndex === -1 ? undefined : stepNameWithVersion.substring(atIndex + 1);
331
+ let inputs = stepConfig?.inputs || {};
332
+ if (Array.isArray(inputs)) {
333
+ const inputsObj = {};
334
+ for (const input of inputs) {
335
+ if (typeof input === 'object' && input !== null) {
336
+ Object.assign(inputsObj, input);
337
+ }
338
+ }
339
+ inputs = inputsObj;
340
+ }
341
+ return {
342
+ name,
343
+ version,
344
+ title: stepConfig?.title,
345
+ inputs,
346
+ run_if: stepConfig?.run_if,
347
+ is_always_run: stepConfig?.is_always_run,
348
+ is_skippable: stepConfig?.is_skippable,
349
+ };
350
+ }
351
+ }
352
+ /**
353
+ * Format validation result for console output
354
+ */
355
+ export function formatValidationResult(result) {
356
+ if (result.valid && result.issues.length === 0) {
357
+ return '\n✅ All pre-execution validations passed\n';
358
+ }
359
+ const lines = [];
360
+ lines.push('\n' + '═'.repeat(70));
361
+ lines.push('PRE-EXECUTION VALIDATION RESULTS');
362
+ lines.push('═'.repeat(70));
363
+ // Summary
364
+ lines.push(`\n📊 Summary: ${result.counts.errors} error${result.counts.errors !== 1 ? 's' : ''}, ` +
365
+ `${result.counts.warnings} warning${result.counts.warnings !== 1 ? 's' : ''}, ` +
366
+ `${result.counts.info} info\n`);
367
+ // Group by step
368
+ for (const [stepName, stepIssues] of result.issuesByStep) {
369
+ const errors = stepIssues.filter((i) => i.requirement.severity === 'error');
370
+ const warnings = stepIssues.filter((i) => i.requirement.severity === 'warning');
371
+ const infos = stepIssues.filter((i) => i.requirement.severity === 'info');
372
+ lines.push(`\n📦 Step: ${stepName}`);
373
+ lines.push('─'.repeat(50));
374
+ for (const issue of errors) {
375
+ lines.push(` ❌ ERROR: ${issue.requirement.description}`);
376
+ lines.push(` ${issue.result.message}`);
377
+ if (issue.requirement.hint) {
378
+ lines.push(` 💡 ${issue.requirement.hint}`);
379
+ }
380
+ }
381
+ for (const issue of warnings) {
382
+ lines.push(` ⚠️ WARNING: ${issue.requirement.description}`);
383
+ lines.push(` ${issue.result.message}`);
384
+ if (issue.requirement.hint) {
385
+ lines.push(` 💡 ${issue.requirement.hint}`);
386
+ }
387
+ }
388
+ for (const issue of infos) {
389
+ lines.push(` ℹ️ INFO: ${issue.requirement.description}`);
390
+ lines.push(` ${issue.result.message}`);
391
+ }
392
+ }
393
+ lines.push('\n' + '═'.repeat(70));
394
+ if (result.counts.errors > 0) {
395
+ lines.push('❌ Validation failed. Please fix the errors above before running the pipeline.');
396
+ }
397
+ else {
398
+ lines.push('⚠️ Validation passed with warnings. Pipeline can proceed.');
399
+ }
400
+ lines.push('═'.repeat(70) + '\n');
401
+ return lines.join('\n');
402
+ }
403
+ //# sourceMappingURL=step-validator.js.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Android signing step: sign-apk
3
+ */
4
+ import { BaseStepExecutor } from './base.js';
5
+ import type { StepDef, CIConfig } from '../../types.js';
6
+ import type { ValidationRequirement, StepOutput } from '../validation-types.js';
7
+ export interface SignApkInputs {
8
+ /** Path(s) to APK or AAB file(s), pipe-separated */
9
+ android_app?: string;
10
+ /** Keystore file URL or local path (file://...) */
11
+ keystore_url?: string;
12
+ /** Keystore password */
13
+ keystore_password?: string;
14
+ /** Key alias inside the keystore */
15
+ keystore_alias?: string;
16
+ /** Private key password (defaults to keystore_password) */
17
+ private_key_password?: string;
18
+ /** Page alignment for .so files: automatic | true | false */
19
+ page_align?: string;
20
+ /** Signing tool: automatic | apksigner | jarsigner */
21
+ signer_tool?: string;
22
+ /** Output artifact name (without extension) */
23
+ output_name?: string;
24
+ /** Enable verbose logging */
25
+ verbose_log?: boolean;
26
+ }
27
+ /**
28
+ * Signs APK/AAB files using apksigner or jarsigner with zipalign.
29
+ */
30
+ export declare class SignApkStepExecutor extends BaseStepExecutor {
31
+ getValidationRequirements(inputs: SignApkInputs, env: Record<string, string>, _config: CIConfig): ValidationRequirement[];
32
+ getOutputs(): StepOutput[];
33
+ execute(inputs: SignApkInputs, _env: Record<string, string>, _config: CIConfig): Promise<StepDef>;
34
+ }
35
+ //# sourceMappingURL=android-sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"android-sign.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/android-sign.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wBAAwB;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,gBAAgB;IACvD,yBAAyB,CACvB,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAM1B,UAAU,IAAI,UAAU,EAAE;IAOpB,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CA0IxG"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Android signing step: sign-apk
3
+ */
4
+ import { BaseStepExecutor } from './base.js';
5
+ /**
6
+ * Signs APK/AAB files using apksigner or jarsigner with zipalign.
7
+ */
8
+ export class SignApkStepExecutor extends BaseStepExecutor {
9
+ getValidationRequirements(inputs, env, _config) {
10
+ return [
11
+ this.requireCommand('zipalign', 'Android zipalign tool is required', 'Install Android SDK Build Tools'),
12
+ ];
13
+ }
14
+ getOutputs() {
15
+ return [
16
+ { name: 'CIBUILD_SIGNED_APK_PATH', type: 'environment', description: 'Path to the signed APK' },
17
+ { name: 'CIBUILD_SIGNED_AAB_PATH', type: 'environment', description: 'Path to the signed AAB' },
18
+ ];
19
+ }
20
+ async execute(inputs, _env, _config) {
21
+ const stepName = 'sign-apk';
22
+ const androidApp = this.getInput(inputs, 'android_app', '$CIBUILD_APK_PATH');
23
+ const keystoreUrl = this.getInput(inputs, 'keystore_url', '$KEYSTORE_URL');
24
+ const keystorePassword = this.getInput(inputs, 'keystore_password', '$KEYSTORE_PASSWORD');
25
+ const keystoreAlias = this.getInput(inputs, 'keystore_alias', '$KEYSTORE_ALIAS');
26
+ const privateKeyPassword = this.getInput(inputs, 'private_key_password', '');
27
+ const pageAlign = this.getInput(inputs, 'page_align', 'automatic');
28
+ const signerTool = this.getInput(inputs, 'signer_tool', 'automatic');
29
+ const outputName = this.getInput(inputs, 'output_name', '');
30
+ const verboseLog = this.getInput(inputs, 'verbose_log', false);
31
+ const commands = [];
32
+ commands.push('# sign-apk — sign Android APK/AAB');
33
+ commands.push('echo "🔐 Signing Android app..."');
34
+ commands.push('');
35
+ // Resolve keystore
36
+ commands.push('# Resolve keystore file');
37
+ commands.push(`KEYSTORE_URL="${keystoreUrl}"`);
38
+ commands.push(`KEYSTORE_PASSWORD="${keystorePassword}"`);
39
+ commands.push(`KEYSTORE_ALIAS="${keystoreAlias}"`);
40
+ if (privateKeyPassword) {
41
+ commands.push(`KEY_PASSWORD="${this.escapeBash(privateKeyPassword)}"`);
42
+ }
43
+ else {
44
+ commands.push('KEY_PASSWORD="$KEYSTORE_PASSWORD"');
45
+ }
46
+ commands.push('');
47
+ commands.push('if [ -z "$KEYSTORE_URL" ] || [ -z "$KEYSTORE_PASSWORD" ] || [ -z "$KEYSTORE_ALIAS" ]; then');
48
+ commands.push(' echo "❌ Error: keystore_url, keystore_password, and keystore_alias are required"');
49
+ commands.push(' exit 1');
50
+ commands.push('fi');
51
+ commands.push('');
52
+ // Download or resolve keystore
53
+ commands.push('# Download or resolve keystore file');
54
+ commands.push('if [[ "$KEYSTORE_URL" == file://* ]]; then');
55
+ commands.push(' KEYSTORE_PATH="${KEYSTORE_URL#file://}"');
56
+ commands.push('elif [[ "$KEYSTORE_URL" == http* ]]; then');
57
+ commands.push(' KEYSTORE_PATH="$(mktemp -t keystore).jks"');
58
+ commands.push(' curl -sSfL "$KEYSTORE_URL" -o "$KEYSTORE_PATH"');
59
+ commands.push('else');
60
+ commands.push(' KEYSTORE_PATH="$KEYSTORE_URL"');
61
+ commands.push('fi');
62
+ commands.push('');
63
+ commands.push('if [ ! -f "$KEYSTORE_PATH" ]; then');
64
+ commands.push(' echo "❌ Error: Keystore file not found: $KEYSTORE_PATH"');
65
+ commands.push(' exit 1');
66
+ commands.push('fi');
67
+ commands.push('');
68
+ // Determine signer tool
69
+ commands.push('# Determine signing tool');
70
+ if (signerTool === 'automatic') {
71
+ commands.push('if command -v apksigner &>/dev/null; then');
72
+ commands.push(' SIGNER="apksigner"');
73
+ commands.push('elif command -v jarsigner &>/dev/null; then');
74
+ commands.push(' SIGNER="jarsigner"');
75
+ commands.push('else');
76
+ commands.push(' echo "❌ Error: Neither apksigner nor jarsigner found"');
77
+ commands.push(' exit 1');
78
+ commands.push('fi');
79
+ }
80
+ else {
81
+ commands.push(`SIGNER="${this.escapeBash(signerTool)}"`);
82
+ }
83
+ commands.push('echo "Using signer: $SIGNER"');
84
+ commands.push('');
85
+ // Process each app file
86
+ commands.push(`ANDROID_APP="${androidApp}"`);
87
+ commands.push('SIGNED_APK_PATH=""');
88
+ commands.push('SIGNED_AAB_PATH=""');
89
+ commands.push('');
90
+ commands.push('IFS="|" read -ra APP_FILES <<< "$ANDROID_APP"');
91
+ commands.push('for APP_FILE in "${APP_FILES[@]}"; do');
92
+ commands.push(' APP_FILE="$(echo "$APP_FILE" | xargs)" # trim whitespace');
93
+ commands.push(' [ -z "$APP_FILE" ] && continue');
94
+ commands.push(' ');
95
+ commands.push(' if [ ! -f "$APP_FILE" ]; then');
96
+ commands.push(' echo "⚠️ File not found: $APP_FILE — skipping"');
97
+ commands.push(' continue');
98
+ commands.push(' fi');
99
+ commands.push(' ');
100
+ commands.push(' EXT="${APP_FILE##*.}"');
101
+ commands.push(' DIR="$(dirname "$APP_FILE")"');
102
+ commands.push(' BASE="$(basename "$APP_FILE" ".$EXT")"');
103
+ if (outputName) {
104
+ commands.push(` OUT_NAME="${this.escapeBash(outputName)}"`);
105
+ }
106
+ else {
107
+ commands.push(' OUT_NAME="${BASE}-signed"');
108
+ }
109
+ commands.push(' SIGNED_FILE="$DIR/${OUT_NAME}.${EXT}"');
110
+ commands.push(' ');
111
+ // zipalign for APKs
112
+ commands.push(' if [ "$EXT" = "apk" ]; then');
113
+ commands.push(' echo "Zipaligning: $APP_FILE"');
114
+ const alignFlag = pageAlign === 'true' ? '-p' : '';
115
+ commands.push(` zipalign ${alignFlag} -f 4 "$APP_FILE" "$DIR/\${BASE}-aligned.apk"`);
116
+ commands.push(' APP_FILE="$DIR/${BASE}-aligned.apk"');
117
+ commands.push(' fi');
118
+ commands.push(' ');
119
+ // Sign
120
+ commands.push(' echo "Signing: $APP_FILE → $SIGNED_FILE"');
121
+ commands.push(' if [ "$SIGNER" = "apksigner" ]; then');
122
+ const verboseFlag = verboseLog ? ' --verbose' : '';
123
+ commands.push(` apksigner sign${verboseFlag} --ks "$KEYSTORE_PATH" --ks-pass "pass:$KEYSTORE_PASSWORD" --ks-key-alias "$KEYSTORE_ALIAS" --key-pass "pass:$KEY_PASSWORD" --out "$SIGNED_FILE" "$APP_FILE"`);
124
+ commands.push(' else');
125
+ commands.push(' cp "$APP_FILE" "$SIGNED_FILE"');
126
+ commands.push(` jarsigner${verboseLog ? ' -verbose' : ''} -keystore "$KEYSTORE_PATH" -storepass "$KEYSTORE_PASSWORD" -keypass "$KEY_PASSWORD" "$SIGNED_FILE" "$KEYSTORE_ALIAS"`);
127
+ commands.push(' fi');
128
+ commands.push(' ');
129
+ // Track outputs
130
+ commands.push(' if [ "$EXT" = "apk" ]; then');
131
+ commands.push(' SIGNED_APK_PATH="$SIGNED_FILE"');
132
+ commands.push(' elif [ "$EXT" = "aab" ]; then');
133
+ commands.push(' SIGNED_AAB_PATH="$SIGNED_FILE"');
134
+ commands.push(' fi');
135
+ commands.push(' echo "✅ Signed: $SIGNED_FILE"');
136
+ commands.push('done');
137
+ commands.push('');
138
+ // Export
139
+ commands.push('# Export signed paths');
140
+ commands.push('[ -n "$SIGNED_APK_PATH" ] && envman add --key CIBUILD_SIGNED_APK_PATH --value "$SIGNED_APK_PATH"');
141
+ commands.push('[ -n "$SIGNED_AAB_PATH" ] && envman add --key CIBUILD_SIGNED_AAB_PATH --value "$SIGNED_AAB_PATH"');
142
+ commands.push('echo "✅ Signing complete"');
143
+ const script = this.createBashScriptFromCommands(commands, stepName);
144
+ return this.createScriptStep(script, stepName);
145
+ }
146
+ }
147
+ //# sourceMappingURL=android-sign.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Android version code and version name step implementation
3
+ * Updates versionCode and versionName in build.gradle
4
+ */
5
+ import { BaseStepExecutor } from './base.js';
6
+ import type { StepDef, CIConfig } from '../../types.js';
7
+ import type { ValidationRequirement, StepOutput } from '../validation-types.js';
8
+ /**
9
+ * Inputs for change-android-versioncode-and-versionname step
10
+ */
11
+ export interface ChangeAndroidVersionInputs {
12
+ build_gradle_path?: string;
13
+ new_version_name?: string;
14
+ new_version_code?: string;
15
+ version_code_offset?: string;
16
+ }
17
+ /**
18
+ * Change Android versionCode and versionName step executor
19
+ * Modifies build.gradle in-place using sed before the build runs
20
+ */
21
+ export declare class ChangeAndroidVersionStepExecutor extends BaseStepExecutor {
22
+ getOutputs(): StepOutput[];
23
+ getValidationRequirements(inputs: ChangeAndroidVersionInputs, _env: Record<string, string>, _config: CIConfig): ValidationRequirement[];
24
+ execute(inputs: ChangeAndroidVersionInputs, _env: Record<string, string>, _config: CIConfig): Promise<StepDef>;
25
+ }
26
+ //# sourceMappingURL=android-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"android-version.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/android-version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,qBAAa,gCAAiC,SAAQ,gBAAgB;IACpE,UAAU,IAAI,UAAU,EAAE;IAO1B,yBAAyB,CACvB,MAAM,EAAE,0BAA0B,EAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAMpB,OAAO,CAAC,MAAM,EAAE,0BAA0B,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CAoHrH"}