gowalk-cicd 1.0.106 → 1.0.107

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.
package/README.md CHANGED
@@ -40,11 +40,12 @@ Merge the exact validated candidate through the repository's protected PR. Only
40
40
  web, documentation and tooling landings do not trigger a store build. Backend and web retain
41
41
  their own workflows. Web compilation no longer starts just because a plugin version marker changed.
42
42
 
43
- The intent binds committed source and a digest of repository variables. A changed source input
44
- or compiled variable refuses before builds; prepare a new intent after the repair. Native iOS
43
+ The intent binds committed source and effective organization/repository variables, with repository
44
+ precedence. A changed source input or compiled variable refuses before builds; prepare a new intent after the repair. Native iOS
45
45
  and Android directories are scoped to their own platform. Unknown inputs, embedded editors,
46
46
  assets, scripts, dependency locks and backend-generated resources remain in the conservative
47
- source fingerprint. There is no blanket editor/backend exclusion from the input proof.
47
+ source fingerprint. Documents remain inputs because an app may bundle them. There is no blanket
48
+ editor/backend exclusion from the input proof. These conservative hashes do not add push triggers.
48
49
 
49
50
  The gate records each platform in GitHub deployment receipts, scoped to that input fingerprint.
50
51
  A confirmed upload is reused on subsequent attempts and emits `mobile_upload_reused` with the
@@ -1 +1 @@
1
- 1.0.106
1
+ 1.0.107
@@ -10,7 +10,8 @@ const digest = value => createHash('sha256').update(value).digest('hex');
10
10
 
11
11
  function input(name, platform) {
12
12
  if (name === INTENT || name.startsWith('.factory/progress/') || name.startsWith('creds/')) return false;
13
- if (/^(README|CHANGELOG|AGENTS|CLAUDE)\.md$/.test(name) || /^docs\/.*\.md$/.test(name)) return false;
13
+ // Documents may be bundled resources or test inputs. Promotion is explicit, so
14
+ // retaining them here cannot make an ordinary documentation push deploy mobile.
14
15
  if (platform === 'ios' && name.startsWith('android/')) return false;
15
16
  if (platform === 'android' && name.startsWith('ios/')) return false;
16
17
  // Backend and web deployment alone never promote a mobile release. Their source
@@ -1 +1 @@
1
- 1.0.106
1
+ 1.0.107
@@ -1 +1 @@
1
- 1.0.106
1
+ 1.0.107
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gowalk-cicd",
3
- "version": "1.0.106",
3
+ "version": "1.0.107",
4
4
  "description": "Zero-config GitHub Actions delivery for iOS TestFlight and Android Google Play.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/release.mjs CHANGED
@@ -2,6 +2,29 @@
2
2
  import {execFileSync} from 'node:child_process';
3
3
  import inputs from '../action/scripts/mobile_inputs.cjs';
4
4
 
5
+ export function variables(repository, execute) {
6
+ const info = JSON.parse(execute('gh', ['api', `repos/${repository}`]));
7
+ if (info.full_name !== repository || !['User', 'Organization'].includes(info.owner?.type)) {
8
+ throw Error('mobile_release_repository_unverified');
9
+ }
10
+ const scopes = info.owner.type === 'Organization' ? ['organization-variables', 'variables'] : ['variables'];
11
+ const result = {};
12
+ for (const scope of scopes) {
13
+ const pages = JSON.parse(execute('gh', ['api', `repos/${repository}/actions/${scope}?per_page=100`,
14
+ '--paginate', '--slurp']));
15
+ if (!Array.isArray(pages) || pages.some(page => !Array.isArray(page.variables))) {
16
+ throw Error('mobile_release_configuration_unverified');
17
+ }
18
+ for (const row of pages.flatMap(page => page.variables)) {
19
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(row.name) || typeof row.value !== 'string') {
20
+ throw Error('mobile_release_configuration_unverified');
21
+ }
22
+ result[row.name] = row.value;
23
+ }
24
+ }
25
+ return result;
26
+ }
27
+
5
28
  export function release(platform) {
6
29
  const execute = (command, args) => execFileSync(command, args, {
7
30
  encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 60000,
@@ -9,8 +32,5 @@ export function release(platform) {
9
32
  const remote = execute('git', ['remote', 'get-url', 'origin']);
10
33
  const match = /^(?:git@github\.com:|https:\/\/github\.com\/)([\w.-]+\/[\w.-]+?)(?:\.git)?$/.exec(remote);
11
34
  if (!match) throw Error('mobile_release_repository_unverified');
12
- const pages = JSON.parse(execute('gh', ['api', `repos/${match[1]}/actions/variables?per_page=100`,
13
- '--paginate', '--slurp']));
14
- const variables = Object.fromEntries(pages.flatMap(page => page.variables).map(row => [row.name, row.value]));
15
- return inputs.create(platform === 'both' ? ['ios', 'android'] : [platform], variables);
35
+ return inputs.create(platform === 'both' ? ['ios', 'android'] : [platform], variables(match[1], execute));
16
36
  }