@empire-builder-kit/nx 1.0.0-rc.13 → 1.0.0-rc.17
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/executors.json +10 -0
- package/package.json +3 -3
- package/src/cli/output.js +1 -1
- package/src/developer-agent/model.js +4 -4
- package/src/developer-agent/model.js.map +1 -1
- package/src/developer-agent/operation-registry.js +53 -8
- package/src/developer-agent/operation-registry.js.map +1 -1
- package/src/developer-agent/planning.js +7 -9
- package/src/developer-agent/planning.js.map +1 -1
- package/src/developer-agent/workspace-inspection.js +12 -0
- package/src/developer-agent/workspace-inspection.js.map +1 -1
- package/src/executors/deployment-plan/deployment-plan.js +5 -0
- package/src/executors/deployment-plan/deployment-plan.js.map +1 -1
- package/src/executors/foundation-preflight/foundation-preflight.d.ts +2 -0
- package/src/executors/foundation-preflight/foundation-preflight.js +6 -2
- package/src/executors/foundation-preflight/foundation-preflight.js.map +1 -1
- package/src/executors/foundation-preflight/schema.json +10 -0
- package/src/executors/foundation-profile-preflight/foundation-profile-preflight.d.ts +2 -0
- package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js +2 -1
- package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +1 -1
- package/src/executors/foundation-profile-preflight/schema.json +19 -3
- package/src/executors/github-bootstrap/github-bootstrap.js +1 -0
- package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -1
- package/src/executors/infrastructure-plan/infrastructure-plan.d.ts +229 -5
- package/src/executors/infrastructure-plan/infrastructure-plan.js +2298 -175
- package/src/executors/infrastructure-plan/infrastructure-plan.js.map +1 -1
- package/src/executors/infrastructure-plan/schema.json +16 -0
- package/src/executors/local-deploy/fixtures/local-deploy-state-machine.mjs +53 -0
- package/src/executors/local-deploy/local-approval.d.ts +23 -0
- package/src/executors/local-deploy/local-approval.js +43 -0
- package/src/executors/local-deploy/local-approval.js.map +1 -0
- package/src/executors/local-deploy/local-deploy.d.ts +69 -0
- package/src/executors/local-deploy/local-deploy.js +911 -0
- package/src/executors/local-deploy/local-deploy.js.map +1 -0
- package/src/executors/local-deploy/schema.json +42 -0
- package/src/executors/router-waf-rehearsal/router-waf-rehearsal.d.ts +3 -0
- package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js +94 -0
- package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js.map +1 -0
- package/src/executors/router-waf-rehearsal/schema.json +9 -0
- package/src/executors/secret-metadata/schema.json +5 -0
- package/src/executors/secret-metadata/secret-metadata.d.ts +12 -1
- package/src/executors/secret-metadata/secret-metadata.js +68 -16
- package/src/executors/secret-metadata/secret-metadata.js.map +1 -1
- package/src/executors/sst-lifecycle/logging-preflight.d.ts +5 -0
- package/src/executors/sst-lifecycle/logging-preflight.js +23 -13
- package/src/executors/sst-lifecycle/logging-preflight.js.map +1 -1
- package/src/executors/sst-lifecycle/run-sst-command.d.ts +8 -1
- package/src/executors/sst-lifecycle/run-sst-command.js +144 -12
- package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -1
- package/src/executors/sst-lifecycle/schema.json +13 -1
- package/src/executors/sst-lifecycle/sst-environment-source.d.ts +25 -0
- package/src/executors/sst-lifecycle/sst-environment-source.js +213 -0
- package/src/executors/sst-lifecycle/sst-environment-source.js.map +1 -0
- package/src/foundation/index.d.ts +2 -0
- package/src/foundation/index.js +2 -0
- package/src/foundation/index.js.map +1 -1
- package/src/foundation/logging-preflight.js +1 -1
- package/src/foundation/logging-preflight.js.map +1 -1
- package/src/foundation/logging.d.ts +3 -1
- package/src/foundation/logging.js +1 -1
- package/src/foundation/logging.js.map +1 -1
- package/src/foundation/partial-state.d.ts +10 -0
- package/src/foundation/partial-state.js +21 -0
- package/src/foundation/partial-state.js.map +1 -0
- package/src/foundation/router-waf.d.ts +98 -0
- package/src/foundation/router-waf.js +401 -0
- package/src/foundation/router-waf.js.map +1 -0
- package/src/generators/function/function.js +2 -1
- package/src/generators/function/function.js.map +1 -1
- package/src/generators/preset/generator.js +23 -3
- package/src/generators/preset/generator.js.map +1 -1
- package/src/generators/preset/schema.d.ts +7 -0
- package/src/generators/preset/schema.json +47 -0
- package/src/generators/preset/workspace-files-ci-acceptance.js +176 -36
- package/src/generators/preset/workspace-files-ci-acceptance.js.map +1 -1
- package/src/generators/preset/workspace-files-developer-agent.d.ts +2 -0
- package/src/generators/preset/workspace-files-developer-agent.js +25 -11
- package/src/generators/preset/workspace-files-developer-agent.js.map +1 -1
- package/src/generators/preset/workspace-files-foundation-workload-roles.js +5 -2
- package/src/generators/preset/workspace-files-foundation-workload-roles.js.map +1 -1
- package/src/generators/preset/workspace-files-workload-role-baseline.js +254 -42
- package/src/generators/preset/workspace-files-workload-role-baseline.js.map +1 -1
- package/src/generators/preset/workspace-files.d.ts +5 -1
- package/src/generators/preset/workspace-files.js +788 -49
- package/src/generators/preset/workspace-files.js.map +1 -1
- package/src/generators/repository-policy/repository-policy.js +65 -3
- package/src/generators/repository-policy/repository-policy.js.map +1 -1
- package/src/generators/repository-policy/schema.d.ts +6 -0
- package/src/generators/repository-policy/schema.json +46 -0
- package/src/generators/slice/built-in-plan-api-files.js +2 -1
- package/src/generators/slice/built-in-plan-api-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +18 -0
- package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-data-files.js +16 -5
- package/src/generators/slice/built-in-plan-data-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-data-retention-job-files.js +6 -3
- package/src/generators/slice/built-in-plan-data-retention-job-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-database-lifecycle-files.js +21 -7
- package/src/generators/slice/built-in-plan-database-lifecycle-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-foundation-files.js +2 -3
- package/src/generators/slice/built-in-plan-foundation-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-infrastructure-files.js +359 -27
- package/src/generators/slice/built-in-plan-infrastructure-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-infrastructure-safety-files.js +67 -11
- package/src/generators/slice/built-in-plan-infrastructure-safety-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-metadata-files.js +1 -0
- package/src/generators/slice/built-in-plan-metadata-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-operations-files.js +442 -5
- package/src/generators/slice/built-in-plan-operations-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-performance-files.d.ts +2 -1
- package/src/generators/slice/built-in-plan-performance-files.js +34 -47
- package/src/generators/slice/built-in-plan-performance-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-project-files.js +14 -2
- package/src/generators/slice/built-in-plan-project-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-release-files.js +119 -30
- package/src/generators/slice/built-in-plan-release-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-web-files.js +13 -0
- package/src/generators/slice/built-in-plan-web-files.js.map +1 -1
- package/src/generators/slice/built-in-plan-workload-role-files.js +5 -2
- package/src/generators/slice/built-in-plan-workload-role-files.js.map +1 -1
- package/src/generators/slice/built-in-plan.d.ts +2 -1
- package/src/generators/slice/built-in-plan.js +8 -5
- package/src/generators/slice/built-in-plan.js.map +1 -1
- package/src/generators/slice/slice.js +11 -3
- package/src/generators/slice/slice.js.map +1 -1
- package/src/generators/upgrade/upgrade.js +35 -0
- package/src/generators/upgrade/upgrade.js.map +1 -1
- package/src/generators/workload/workload.js +2 -2
- package/src/generators/workload/workload.js.map +1 -1
- package/src/git-policy/github-bootstrap.d.ts +3 -1
- package/src/git-policy/github-bootstrap.js +22 -5
- package/src/git-policy/github-bootstrap.js.map +1 -1
- package/src/infrastructure-change/local-capability.d.ts +73 -0
- package/src/infrastructure-change/local-capability.js +114 -0
- package/src/infrastructure-change/local-capability.js.map +1 -0
- package/src/infrastructure-change/model.d.ts +25 -4
- package/src/infrastructure-change/model.js +1 -0
- package/src/infrastructure-change/model.js.map +1 -1
- package/src/infrastructure-change/normalize.d.ts +4 -0
- package/src/infrastructure-change/normalize.js +47 -7
- package/src/infrastructure-change/normalize.js.map +1 -1
- package/src/infrastructure-change/plan.d.ts +30 -3
- package/src/infrastructure-change/plan.js +323 -13
- package/src/infrastructure-change/plan.js.map +1 -1
- package/src/infrastructure-change/risk.d.ts +3 -1
- package/src/infrastructure-change/risk.js +96 -16
- package/src/infrastructure-change/risk.js.map +1 -1
- package/src/local-dev/private-state.d.ts +2 -0
- package/src/local-dev/private-state.js +3 -1
- package/src/local-dev/private-state.js.map +1 -1
- package/src/performance/cost-controls.d.ts +5 -3
- package/src/performance/cost-controls.js +30 -24
- package/src/performance/cost-controls.js.map +1 -1
- package/src/performance/model.d.ts +1 -1
- package/src/performance/model.js +0 -2
- package/src/performance/model.js.map +1 -1
- package/src/performance/test-fixtures.js +0 -2
- package/src/performance/test-fixtures.js.map +1 -1
- package/src/release/source-authority.d.ts +1 -0
- package/src/release/source-authority.js +136 -9
- package/src/release/source-authority.js.map +1 -1
- package/src/repository-policy/deployment-plan.d.ts +4 -1
- package/src/repository-policy/deployment-plan.js +8 -0
- package/src/repository-policy/deployment-plan.js.map +1 -1
- package/src/repository-policy/foundation-profile.js +1 -2
- package/src/repository-policy/foundation-profile.js.map +1 -1
- package/src/repository-policy/policy.d.ts +25 -1
- package/src/repository-policy/policy.js +145 -4
- package/src/repository-policy/policy.js.map +1 -1
- package/src/schemas/performance-policy-v1.json +0 -2
- package/src/schemas/repository-policy-v1.json +41 -0
- package/src/secrets/operator.js +22 -4
- package/src/secrets/operator.js.map +1 -1
- package/src/secrets/verification.js +9 -1
- package/src/secrets/verification.js.map +1 -1
- package/src/sst-environment-source-format.d.ts +3 -0
- package/src/sst-environment-source-format.js +179 -0
- package/src/sst-environment-source-format.js.map +1 -0
- package/src/supply-chain/blueprint-verification-authority.js +55 -3
- package/src/supply-chain/blueprint-verification-authority.js.map +1 -1
- package/src/supply-chain/generated-command.js +1 -0
- package/src/supply-chain/generated-command.js.map +1 -1
- package/src/supply-chain/generated-container-release-command.js +187 -38
- package/src/supply-chain/generated-container-release-command.js.map +1 -1
- package/src/supply-chain/generated-ecr-collector-command.js +12 -2
- package/src/supply-chain/generated-ecr-collector-command.js.map +1 -1
- package/src/supply-chain/generated-scanner-command.js +1 -0
- package/src/supply-chain/generated-scanner-command.js.map +1 -1
- package/src/supply-chain/sbom.d.ts +1 -1
- package/src/supply-chain/sbom.js +30 -5
- package/src/supply-chain/sbom.js.map +1 -1
- package/src/workload-roles/account-baseline.d.ts +11 -0
- package/src/workload-roles/account-baseline.js +253 -16
- package/src/workload-roles/account-baseline.js.map +1 -1
- package/src/workload-roles/authority.d.ts +3 -1
- package/src/workload-roles/authority.js +48 -2
- package/src/workload-roles/authority.js.map +1 -1
- package/src/workload-roles/aws-s3-state.js +27 -0
- package/src/workload-roles/aws-s3-state.js.map +1 -1
- package/src/workload-roles/boundary.d.ts +2 -1
- package/src/workload-roles/boundary.js +9 -2
- package/src/workload-roles/boundary.js.map +1 -1
- package/src/workload-roles/handler.js +52 -24
- package/src/workload-roles/handler.js.map +1 -1
- package/src/workload-roles/injection.js +1 -1
- package/src/workload-roles/injection.js.map +1 -1
- package/src/workload-roles/provisioner.js +12 -4
- package/src/workload-roles/provisioner.js.map +1 -1
- package/src/workload-roles/registration.d.ts +1 -0
- package/src/workload-roles/registration.js +5 -0
- package/src/workload-roles/registration.js.map +1 -1
- package/src/workload-roles/stage-boundary.js +1 -1
- package/src/workload-roles/stage-boundary.js.map +1 -1
- package/src/workload-roles/standard-slice.js +1 -0
- package/src/workload-roles/standard-slice.js.map +1 -1
|
@@ -41,7 +41,7 @@ function createFunctionFilePlan(workspace, slice, name, feature = name) {
|
|
|
41
41
|
files: {
|
|
42
42
|
[`api/${name}.ts`]: `import { createHttpJsonHandler } from '@empire-builder-kit/runtime';\n\nexport const handler = createHttpJsonHandler({\n component: 'function-${name}',\n feature: '${feature}',\n operation: '${name}',\n slice: '${slice}',\n workspace: '${workspace}',\n async handle({ context }) {\n return { actor: context.actor?.id ?? null, function: '${name}', ok: true };\n },\n});\n`,
|
|
43
43
|
[`api/${name}.spec.ts`]: `import { describe, expect, it } from 'vitest';\nimport { handler } from './${name}.js';\n\ndescribe('${name} function', () => {\n it('returns its generated identity', async () => {\n const response = await handler({ requestContext: { requestId: 'test-request' } });\n expect(response.statusCode).toBe(200);\n expect(JSON.parse(response.body).data).toMatchObject({ function: '${name}', ok: true });\n });\n});\n`,
|
|
44
|
-
[`infra/functions/${name}.ts`]: `import { createManagedLogGroupContract } from '@empire-builder-kit/nx/foundation';\n\nexport function ${register}(\n api: any,\n alertTopicArn: any,\n role?: { role: string },\n links: any[] = [],\n) {\n const contract = createManagedLogGroupContract({\n component: 'function-${name}',\n slice: '${slice}',\n stage: $app.stage,\n workspace: '${workspace}',\n });\n const logGroup = new aws.cloudwatch.LogGroup('${pascal(slice)}${pascal(name)}Logs', {\n logGroupClass: contract.logGroupClass,\n name: contract.name,\n retentionInDays: contract.retentionInDays,\n tags: contract.tags,\n });\n const dataProtection = new aws.cloudwatch.LogDataProtectionPolicy(\n '${pascal(slice)}${pascal(name)}LogDataProtection',\n {\n logGroupName: logGroup.name,\n policyDocument: JSON.stringify(contract.dataProtectionPolicy),\n },\n { dependsOn: [logGroup] },\n );\n const dataProtectionAlarm = new aws.cloudwatch.MetricAlarm(\n '${pascal(slice)}${pascal(name)}LogDataProtectionFindings',\n {\n alarmActions: [alertTopicArn],\n comparisonOperator: 'GreaterThanOrEqualToThreshold',\n dimensions: { LogGroupName: logGroup.name },\n evaluationPeriods: 1,\n metricName: 'LogEventsWithFindings',\n namespace: 'AWS/Logs',\n period: 300,\n statistic: 'Sum',\n threshold: 1,\n treatMissingData: 'notBreaching',\n },\n { dependsOn: [dataProtection] },\n );\n api.route('ANY /functions/${name}', {\n ...(role ?? {}),\n environment: { EBK_STAGE: $app.stage },\n handler: 'api/${name}.handler',\n link: links,\n logging: { format: 'json', logGroup: logGroup.name },\n transform: {\n function: {\n loggingConfig: {\n applicationLogLevel: 'TRACE',\n logFormat: 'JSON',\n logGroup: logGroup.name,\n systemLogLevel: 'INFO',\n },\n },\n },\n });\n return { dataProtection, dataProtectionAlarm, logGroup };\n}\n`,
|
|
44
|
+
[`infra/functions/${name}.ts`]: `import { createManagedLogGroupContract } from '@empire-builder-kit/nx/foundation';\n\nexport function ${register}(\n api: any,\n router: any,\n alertTopicArn: any,\n role?: { role: string },\n links: any[] = [],\n) {\n const contract = createManagedLogGroupContract({\n component: 'function-${name}',\n slice: '${slice}',\n stage: $app.stage,\n workspace: '${workspace}',\n });\n const logGroup = new aws.cloudwatch.LogGroup('${pascal(slice)}${pascal(name)}Logs', {\n logGroupClass: contract.logGroupClass,\n name: contract.name,\n retentionInDays: contract.retentionInDays,\n tags: contract.tags,\n });\n const dataProtection = new aws.cloudwatch.LogDataProtectionPolicy(\n '${pascal(slice)}${pascal(name)}LogDataProtection',\n {\n logGroupName: logGroup.name,\n policyDocument: JSON.stringify(contract.dataProtectionPolicy),\n },\n { dependsOn: [logGroup] },\n );\n const dataProtectionAlarm = new aws.cloudwatch.MetricAlarm(\n '${pascal(slice)}${pascal(name)}LogDataProtectionFindings',\n {\n alarmActions: [alertTopicArn],\n comparisonOperator: 'GreaterThanOrEqualToThreshold',\n dimensions: { LogGroupName: logGroup.name },\n evaluationPeriods: 1,\n metricName: 'LogEventsWithFindings',\n namespace: 'AWS/Logs',\n period: 300,\n statistic: 'Sum',\n threshold: 1,\n treatMissingData: 'notBreaching',\n },\n { dependsOn: [dataProtection] },\n );\n const functionPath = '/functions/${name}';\n const routerPath = '/${slice}/api/functions/${name}';\n api.route('ANY /functions/${name}', {\n ...(role ?? {}),\n ebkRouteMaterialization: 'direct',\n environment: { EBK_STAGE: $app.stage },\n handler: 'api/${name}.handler',\n link: links,\n logging: { format: 'json', logGroup: logGroup.name },\n transform: {\n function: {\n loggingConfig: {\n applicationLogLevel: 'TRACE',\n logFormat: 'JSON',\n logGroup: logGroup.name,\n systemLogLevel: 'INFO',\n },\n },\n },\n });\n router.route(routerPath, api.url, {\n rewrite: { regex: \`^\${routerPath}$\`, to: functionPath },\n });\n return { dataProtection, dataProtectionAlarm, logGroup };\n}\n`,
|
|
45
45
|
},
|
|
46
46
|
paths: [
|
|
47
47
|
{ mode: 'seeded', path: `api/${name}.ts` },
|
|
@@ -92,6 +92,7 @@ async function functionGenerator(tree, options) {
|
|
|
92
92
|
replaceMarker(tree, productPath, '// <ebk:composition-imports:end>', `import { ${plan.register} } from './functions/${name}.js';`);
|
|
93
93
|
replaceMarker(tree, productPath, '// <ebk:function-registrations:end>', ` ${plan.register}(
|
|
94
94
|
api,
|
|
95
|
+
foundation.router,
|
|
95
96
|
foundation.discovery.alertTopicArn,
|
|
96
97
|
workloadRoleBindings?.extension.function('${name}'),
|
|
97
98
|
secretLinksFor('${name}-function'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/function/function.ts"],"names":[],"mappings":";;AA8DA,wDAqBC;AAED,
|
|
1
|
+
{"version":3,"file":"function.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/function/function.ts"],"names":[],"mappings":";;AA8DA,wDAqBC;AAED,8CAyHC;AA9MD,uCAAoD;AACpD,yCAAkC;AAClC,uDAAsE;AACtE,gEAAuE;AACvE,gEAGgC;AAChC,8EAA8F;AAG9F,SAAS,WAAW,CAAC,KAAa,EAAE,KAAa;IAC/C,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,2FAA2F,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CACpB,IAAU,EACV,IAAY,EACZ,MAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,oCAAoC,MAAM,oBAAoB,IAAI,GAAG,CACtE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,wBAAwB,CAC/B,IAAU,EACV,IAAY,EACZ,MAAc;IAEd,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,oCAAoC,MAAM,oBAAoB,IAAI,GAAG,CACtE,CAAC;IACJ,CAAC;AACH,CAAC;AAQD,SAAgB,sBAAsB,CACpC,SAAiB,EACjB,KAAa,EACb,IAAY,EACZ,OAAO,GAAG,IAAI;IAEd,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;IACzD,MAAM,QAAQ,GAAG,WAAW,MAAM,EAAE,CAAC;IACrC,OAAO;QACL,KAAK,EAAE;YACL,CAAC,OAAO,IAAI,KAAK,CAAC,EAAE,kJAAkJ,IAAI,mBAAmB,OAAO,qBAAqB,IAAI,iBAAiB,KAAK,qBAAqB,SAAS,gGAAgG,IAAI,6BAA6B;YAClZ,CAAC,OAAO,IAAI,UAAU,CAAC,EAAE,8EAA8E,IAAI,sBAAsB,IAAI,wRAAwR,IAAI,+BAA+B;YAChc,CAAC,mBAAmB,IAAI,KAAK,CAAC,EAAE,yGAAyG,QAAQ,8LAA8L,IAAI,mBAAmB,KAAK,+CAA+C,SAAS,8DAA8D,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,+OAA+O,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,2PAA2P,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,seAAse,IAAI,8BAA8B,KAAK,kBAAkB,IAAI,mCAAmC,IAAI,sIAAsI,IAAI,4fAA4f;SAChvE;QACD,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,EAAE;YAC1C,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,IAAI,UAAU,EAAE;YAC/C,EAAE,IAAI,EAAE,mBAAmB,IAAI,KAAK,EAAE;SACvC;QACD,QAAQ;KACT,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,IAAU,EACV,OAAgC;IAEhC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,WAAoB,CAAC;IACzB,IAAI,CAAC;QACH,WAAW,GAAI,IAAI,CAAC,KAAK,CAAC,aAAa,CAAwB,CAAC,IAAI,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,SAAS,GAAG,WAAW,CAC3B,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAClD,gBAAgB,CACjB,CAAC;IACF,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACxD,IAAA,0EAA6C,EAC3C,IAAI,EACJ,sBAAsB,KAAK,IAAI,IAAI,EAAE,CACtC,CAAC;IACF,MAAM,SAAS,GAAG,iBAAK,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,iBAAK,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,iBAAK,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,iBAAK,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC9D,MAAM,aAAa,GAAG,iBAAK,CAAC,IAAI,CAC9B,SAAS,EACT,mCAAmC,CACpC,CAAC;IACF,MAAM,UAAU,GAAG,iBAAK,CAAC,IAAI,CAC3B,SAAS,EACT,0CAA0C,CAC3C,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;IAC9D,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,oCAAoC,KAAK,GAAG,CAC7D,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,IAAA,mDAA6B,EAC3C,IAAI,EACJ,SAAS,EACT,OAAO,CAAC,OAAO,CAChB,CAAC;IACF,wBAAwB,CACtB,IAAI,EACJ,aAAa,EACb,uCAAuC,CACxC,CAAC;IACF,wBAAwB,CACtB,IAAI,EACJ,UAAU,EACV,iDAAiD,CAClD,CAAC;IACF,wBAAwB,CACtB,IAAI,EACJ,WAAW,EACX,kCAAkC,CACnC,CAAC;IACF,wBAAwB,CACtB,IAAI,EACJ,WAAW,EACX,qCAAqC,CACtC,CAAC;IACF,MAAM,mBAAmB,GAAG,IAAA,2DAAqC,EAC/D,IAAI,EACJ,SAAS,EACT,YAAY,IAAI,EAAE,CACnB,CAAC;IACF,MAAM,IAAI,GAAG,sBAAsB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACrE,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,iBAAK,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACnE,aAAa,CACX,IAAI,EACJ,WAAW,EACX,kCAAkC,EAClC,YAAY,IAAI,CAAC,QAAQ,wBAAwB,IAAI,OAAO,CAC7D,CAAC;IACF,aAAa,CACX,IAAI,EACJ,WAAW,EACX,qCAAqC,EACrC,KAAK,IAAI,CAAC,QAAQ;;;;gDAI0B,IAAI;sBAC9B,IAAI;KACrB,CACF,CAAC;IACF,aAAa,CACX,IAAI,EACJ,aAAa,EACb,uCAAuC,EACvC,YAAY,IAAI,wBAAwB,CACzC,CAAC;IACF,aAAa,CACX,IAAI,EACJ,UAAU,EACV,iDAAiD,EACjD,uEAAuE,IAAI,iBAAiB,CAC7F,CAAC;IAEF,IAAI,CAAC,OAAO,CAAC,UAAU;QAAE,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;IACjD,IAAA,qCAA0B,EAAC,IAAI,EAAE;QAC/B,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QACnD,KAAK,EAAE;YACL,GAAG,IAAI,CAAC,KAAK;YACb,EAAE,IAAI,EAAE,kBAAkB,EAAE;YAC5B,EAAE,IAAI,EAAE,mCAAmC,EAAE;YAC7C,EAAE,IAAI,EAAE,0CAA0C,EAAE;YACpD,EAAE,IAAI,EAAE,iDAA2B,EAAE;SACtC;QACD,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED,kBAAe,iBAAiB,CAAC"}
|
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.frameworkPackageVersion = frameworkPackageVersion;
|
|
4
4
|
exports.presetGenerator = presetGenerator;
|
|
5
5
|
const prettier_1 = require("prettier");
|
|
6
|
-
const index_js_1 = require("../../
|
|
6
|
+
const index_js_1 = require("../../repository-policy/index.js");
|
|
7
|
+
const index_js_2 = require("../../ownership/index.js");
|
|
7
8
|
const workspace_files_1 = require("./workspace-files");
|
|
8
9
|
function frameworkPackageVersion() {
|
|
9
10
|
const manifest = require('../../../package.json');
|
|
@@ -13,7 +14,26 @@ function frameworkPackageVersion() {
|
|
|
13
14
|
return manifest.version;
|
|
14
15
|
}
|
|
15
16
|
async function presetGenerator(tree, options) {
|
|
17
|
+
const suppliedAccounts = [
|
|
18
|
+
options.developmentAccountId,
|
|
19
|
+
options.stagingAccountId,
|
|
20
|
+
options.productionAccountId,
|
|
21
|
+
];
|
|
22
|
+
if (suppliedAccounts.some((value) => value !== undefined) &&
|
|
23
|
+
suppliedAccounts.some((value) => value === undefined)) {
|
|
24
|
+
throw new Error('Preset deployment topology requires all three exact stage account IDs together.');
|
|
25
|
+
}
|
|
26
|
+
const deploymentAccounts = suppliedAccounts.every((value) => value !== undefined)
|
|
27
|
+
? (0, index_js_1.validateDeploymentAccountTopology)(options.deploymentProfile ?? 'starter', {
|
|
28
|
+
development: (0, index_js_1.normalizeDeploymentAccountId)(options.developmentAccountId, 'Development deployment account'),
|
|
29
|
+
production: (0, index_js_1.normalizeDeploymentAccountId)(options.productionAccountId, 'Production deployment account'),
|
|
30
|
+
staging: (0, index_js_1.normalizeDeploymentAccountId)(options.stagingAccountId, 'Staging deployment account'),
|
|
31
|
+
})
|
|
32
|
+
: { development: null, production: null, staging: null };
|
|
16
33
|
const renderedFiles = (0, workspace_files_1.renderWorkspaceFiles)({
|
|
34
|
+
deploymentAccounts,
|
|
35
|
+
deploymentProfile: options.deploymentProfile ?? 'starter',
|
|
36
|
+
deploymentRegion: options.deploymentRegion ?? null,
|
|
17
37
|
frameworkVersion: options.frameworkVersion ?? frameworkPackageVersion(),
|
|
18
38
|
name: options.name,
|
|
19
39
|
});
|
|
@@ -37,8 +57,8 @@ async function presetGenerator(tree, options) {
|
|
|
37
57
|
for (const [path, contents] of Object.entries(files)) {
|
|
38
58
|
tree.write(path, contents);
|
|
39
59
|
}
|
|
40
|
-
(0,
|
|
41
|
-
(0,
|
|
60
|
+
(0, index_js_2.restampFoundationOwnership)(tree);
|
|
61
|
+
(0, index_js_2.restampWorkspaceOwnership)(tree);
|
|
42
62
|
}
|
|
43
63
|
exports.default = presetGenerator;
|
|
44
64
|
//# sourceMappingURL=generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/preset/generator.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/preset/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
import type { DeploymentProfile } from '../../repository-policy/index.js';
|
|
2
|
+
|
|
1
3
|
export interface PresetGeneratorSchema {
|
|
4
|
+
deploymentProfile?: DeploymentProfile;
|
|
5
|
+
deploymentRegion?: string;
|
|
6
|
+
developmentAccountId?: string | number;
|
|
2
7
|
frameworkVersion?: string;
|
|
3
8
|
name: string;
|
|
9
|
+
productionAccountId?: string | number;
|
|
10
|
+
stagingAccountId?: string | number;
|
|
4
11
|
}
|
|
@@ -4,6 +4,29 @@
|
|
|
4
4
|
"title": "Empire Builder Kit workspace preset",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
+
"deploymentProfile": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"enum": ["starter", "production-isolated", "fully-isolated"],
|
|
10
|
+
"default": "starter",
|
|
11
|
+
"description": "AWS account and deployment-authority topology."
|
|
12
|
+
},
|
|
13
|
+
"deploymentRegion": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"pattern": "^[a-z]{2}(-gov)?-[a-z]+(-[a-z]+)*-[0-9]$",
|
|
16
|
+
"description": "Optional exact shared AWS Region for all canonical stages."
|
|
17
|
+
},
|
|
18
|
+
"developmentAccountId": {
|
|
19
|
+
"anyOf": [
|
|
20
|
+
{ "type": "string", "pattern": "^[0-9]{12}$" },
|
|
21
|
+
{
|
|
22
|
+
"type": "number",
|
|
23
|
+
"minimum": 100000000000,
|
|
24
|
+
"maximum": 999999999999,
|
|
25
|
+
"multipleOf": 1
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"description": "Optional exact development AWS account ID. Supply all three stage accounts together."
|
|
29
|
+
},
|
|
7
30
|
"name": {
|
|
8
31
|
"type": "string",
|
|
9
32
|
"description": "Workspace name.",
|
|
@@ -16,6 +39,30 @@
|
|
|
16
39
|
"frameworkVersion": {
|
|
17
40
|
"type": "string",
|
|
18
41
|
"description": "Framework package version written to the generated workspace. Defaults to the preset package version."
|
|
42
|
+
},
|
|
43
|
+
"stagingAccountId": {
|
|
44
|
+
"anyOf": [
|
|
45
|
+
{ "type": "string", "pattern": "^[0-9]{12}$" },
|
|
46
|
+
{
|
|
47
|
+
"type": "number",
|
|
48
|
+
"minimum": 100000000000,
|
|
49
|
+
"maximum": 999999999999,
|
|
50
|
+
"multipleOf": 1
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"description": "Optional exact staging AWS account ID. Supply all three stage accounts together."
|
|
54
|
+
},
|
|
55
|
+
"productionAccountId": {
|
|
56
|
+
"anyOf": [
|
|
57
|
+
{ "type": "string", "pattern": "^[0-9]{12}$" },
|
|
58
|
+
{
|
|
59
|
+
"type": "number",
|
|
60
|
+
"minimum": 100000000000,
|
|
61
|
+
"maximum": 999999999999,
|
|
62
|
+
"multipleOf": 1
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"description": "Optional exact production AWS account ID. Supply all three stage accounts together."
|
|
19
66
|
}
|
|
20
67
|
},
|
|
21
68
|
"required": ["name"]
|
|
@@ -19,9 +19,22 @@ import { pathToFileURL } from 'node:url';
|
|
|
19
19
|
import { inflateRawSync } from 'node:zlib';
|
|
20
20
|
|
|
21
21
|
const WORKFLOW = '.github/workflows/ci.yml';
|
|
22
|
-
const KIND = 'ebk-workspace-protected-
|
|
22
|
+
const KIND = 'ebk-workspace-protected-route-acceptance';
|
|
23
|
+
const SCHEMA_VERSION = 2;
|
|
23
24
|
const MAX_ARCHIVE_BYTES = 1024 * 1024;
|
|
24
25
|
const MAX_MANIFEST_BYTES = 256 * 1024;
|
|
26
|
+
const ROUTES = Object.freeze({
|
|
27
|
+
'protected-develop-promotion': Object.freeze({
|
|
28
|
+
base: 'main',
|
|
29
|
+
head: 'develop',
|
|
30
|
+
historyOnly: false,
|
|
31
|
+
}),
|
|
32
|
+
'protected-main-sync': Object.freeze({
|
|
33
|
+
base: 'develop',
|
|
34
|
+
head: 'main',
|
|
35
|
+
historyOnly: true,
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
25
38
|
const INPUTS = Object.freeze([
|
|
26
39
|
WORKFLOW,
|
|
27
40
|
'.node-version',
|
|
@@ -115,6 +128,13 @@ function integer(value, label) {
|
|
|
115
128
|
return value;
|
|
116
129
|
}
|
|
117
130
|
|
|
131
|
+
function commit(value, label) {
|
|
132
|
+
if (typeof value !== 'string' || !/^[a-f0-9]{40}$/u.test(value)) {
|
|
133
|
+
throw new Error(\`Workspace acceptance \${label} commit is invalid.\`);
|
|
134
|
+
}
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
|
|
118
138
|
function repository(value) {
|
|
119
139
|
if (
|
|
120
140
|
typeof value !== 'string' ||
|
|
@@ -129,7 +149,7 @@ function repository(value) {
|
|
|
129
149
|
// GitHub resolves pull_request workflows through an ephemeral merge ref. The
|
|
130
150
|
// workflow bytes and exact source tree are bound independently in the sealed
|
|
131
151
|
// manifest, while this check binds the observable GitHub route.
|
|
132
|
-
function
|
|
152
|
+
function isPullRequestWorkflowRef(value, expectedRepository) {
|
|
133
153
|
const prefix = \`\${expectedRepository}/\${WORKFLOW}@refs/pull/\`;
|
|
134
154
|
return (
|
|
135
155
|
typeof value === 'string' &&
|
|
@@ -138,6 +158,39 @@ function isPromotionWorkflowRef(value, expectedRepository) {
|
|
|
138
158
|
);
|
|
139
159
|
}
|
|
140
160
|
|
|
161
|
+
function routeDefinition(value) {
|
|
162
|
+
if (typeof value !== 'string' || !Object.hasOwn(ROUTES, value)) {
|
|
163
|
+
throw new Error('Workspace acceptance route is invalid.');
|
|
164
|
+
}
|
|
165
|
+
return ROUTES[value];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function routeForBranches(base, head) {
|
|
169
|
+
const matches = Object.entries(ROUTES).filter(
|
|
170
|
+
([, route]) => route.base === base && route.head === head,
|
|
171
|
+
);
|
|
172
|
+
if (matches.length !== 1) {
|
|
173
|
+
throw new Error('Workspace acceptance branch route is invalid.');
|
|
174
|
+
}
|
|
175
|
+
return { name: matches[0][0], ...matches[0][1] };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function routeForProtectedPush(ref) {
|
|
179
|
+
if (ref === 'refs/heads/main') {
|
|
180
|
+
return {
|
|
181
|
+
name: 'protected-develop-promotion',
|
|
182
|
+
...ROUTES['protected-develop-promotion'],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (ref === 'refs/heads/develop') {
|
|
186
|
+
return {
|
|
187
|
+
name: 'protected-main-sync',
|
|
188
|
+
...ROUTES['protected-main-sync'],
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
throw new Error('Workspace merge lookup lacks protected branch authority.');
|
|
192
|
+
}
|
|
193
|
+
|
|
141
194
|
function canonical(value) {
|
|
142
195
|
if (Array.isArray(value)) return value.map(canonical);
|
|
143
196
|
if (value !== null && typeof value === 'object') {
|
|
@@ -159,36 +212,50 @@ export function sealWorkspaceAcceptance({
|
|
|
159
212
|
const expectedRepository = repository(environment.GITHUB_REPOSITORY);
|
|
160
213
|
const runId = integer(environment.GITHUB_RUN_ID, 'run id');
|
|
161
214
|
const runAttempt = integer(environment.GITHUB_RUN_ATTEMPT, 'run attempt');
|
|
215
|
+
const route = routeForBranches(
|
|
216
|
+
environment.GITHUB_BASE_REF,
|
|
217
|
+
environment.GITHUB_HEAD_REF,
|
|
218
|
+
);
|
|
219
|
+
const baseCommit = commit(environment.EBK_BASE_COMMIT, 'base');
|
|
220
|
+
const baseTree = git(root, ['rev-parse', \`\${baseCommit}^{tree}\`]);
|
|
162
221
|
if (
|
|
163
222
|
environment.GITHUB_EVENT_NAME !== 'pull_request' ||
|
|
164
223
|
environment.EBK_HEAD_REPOSITORY !== expectedRepository ||
|
|
165
|
-
|
|
166
|
-
environment.GITHUB_HEAD_REF !== 'develop' ||
|
|
167
|
-
!isPromotionWorkflowRef(
|
|
224
|
+
!isPullRequestWorkflowRef(
|
|
168
225
|
environment.GITHUB_WORKFLOW_REF,
|
|
169
226
|
expectedRepository,
|
|
170
227
|
) ||
|
|
171
228
|
environment.EBK_CI_CANDIDATE_SHA !== source.commit
|
|
172
229
|
) {
|
|
173
|
-
throw new Error(
|
|
174
|
-
'Workspace acceptance is not the protected develop-to-main route.',
|
|
175
|
-
);
|
|
230
|
+
throw new Error('Workspace acceptance is not an exact protected route.');
|
|
176
231
|
}
|
|
177
232
|
if (existsSync(output)) {
|
|
178
233
|
throw new Error('Workspace acceptance output already exists.');
|
|
179
234
|
}
|
|
235
|
+
if (route.historyOnly && baseTree !== source.tree) {
|
|
236
|
+
return Object.freeze({
|
|
237
|
+
base: route.base,
|
|
238
|
+
head: route.head,
|
|
239
|
+
historyOnly: true,
|
|
240
|
+
reason: 'protected main sync changes protected source',
|
|
241
|
+
route: route.name,
|
|
242
|
+
sealed: false,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
180
245
|
const manifest = {
|
|
181
|
-
base:
|
|
246
|
+
base: route.base,
|
|
247
|
+
baseSource: { commit: baseCommit, tree: baseTree },
|
|
182
248
|
eventName: 'pull_request',
|
|
183
|
-
head:
|
|
249
|
+
head: route.head,
|
|
184
250
|
headRepository: expectedRepository,
|
|
251
|
+
historyOnly: route.historyOnly,
|
|
185
252
|
inputs: digests(root),
|
|
186
253
|
kind: KIND,
|
|
187
254
|
repository: expectedRepository,
|
|
188
|
-
route:
|
|
255
|
+
route: route.name,
|
|
189
256
|
runAttempt,
|
|
190
257
|
runId,
|
|
191
|
-
schemaVersion:
|
|
258
|
+
schemaVersion: SCHEMA_VERSION,
|
|
192
259
|
source,
|
|
193
260
|
workflow: WORKFLOW,
|
|
194
261
|
};
|
|
@@ -201,26 +268,35 @@ export function sealWorkspaceAcceptance({
|
|
|
201
268
|
}
|
|
202
269
|
|
|
203
270
|
export function verifyWorkspaceAcceptance({
|
|
271
|
+
baseCommit: requestedBaseCommit,
|
|
204
272
|
headCommit,
|
|
205
273
|
manifestPath,
|
|
206
274
|
repository: requestedRepository,
|
|
207
275
|
root: requested,
|
|
276
|
+
route: requestedRoute,
|
|
208
277
|
runAttempt,
|
|
209
278
|
runId,
|
|
210
279
|
}) {
|
|
211
280
|
const { root, source } = rootIdentity(requested);
|
|
212
281
|
const expectedRepository = repository(requestedRepository);
|
|
282
|
+
const route = {
|
|
283
|
+
name: requestedRoute,
|
|
284
|
+
...routeDefinition(requestedRoute),
|
|
285
|
+
};
|
|
213
286
|
runId = integer(runId, 'run id');
|
|
214
287
|
runAttempt = integer(runAttempt, 'run attempt');
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
288
|
+
const baseCommit = commit(requestedBaseCommit, 'base');
|
|
289
|
+
headCommit = commit(headCommit, 'head');
|
|
290
|
+
const baseTree = git(root, ['rev-parse', \`\${baseCommit}^{tree}\`]);
|
|
218
291
|
const headTree = git(root, ['rev-parse', \`\${headCommit}^{tree}\`]);
|
|
219
292
|
if (headTree !== source.tree) {
|
|
220
293
|
throw new Error(
|
|
221
294
|
'Workspace acceptance head tree differs from the merged tree.',
|
|
222
295
|
);
|
|
223
296
|
}
|
|
297
|
+
if (route.historyOnly && baseTree !== headTree) {
|
|
298
|
+
throw new Error('Workspace acceptance sync changes protected source.');
|
|
299
|
+
}
|
|
224
300
|
const manifest = JSON.parse(
|
|
225
301
|
file(
|
|
226
302
|
path.dirname(manifestPath),
|
|
@@ -228,18 +304,31 @@ export function verifyWorkspaceAcceptance({
|
|
|
228
304
|
256 * 1024,
|
|
229
305
|
).toString('utf8'),
|
|
230
306
|
);
|
|
307
|
+
if (manifest?.kind !== KIND) {
|
|
308
|
+
throw new Error('Workspace acceptance kind is unsupported.');
|
|
309
|
+
}
|
|
310
|
+
if (manifest.schemaVersion !== SCHEMA_VERSION) {
|
|
311
|
+
throw new Error(
|
|
312
|
+
\`Workspace acceptance schema is unsupported; expected schema v\${SCHEMA_VERSION}.\`,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
if (manifest.route !== route.name) {
|
|
316
|
+
throw new Error('Workspace acceptance route differs from the merged route.');
|
|
317
|
+
}
|
|
231
318
|
const expected = {
|
|
232
|
-
base:
|
|
319
|
+
base: route.base,
|
|
320
|
+
baseSource: { commit: baseCommit, tree: baseTree },
|
|
233
321
|
eventName: 'pull_request',
|
|
234
|
-
head:
|
|
322
|
+
head: route.head,
|
|
235
323
|
headRepository: expectedRepository,
|
|
324
|
+
historyOnly: route.historyOnly,
|
|
236
325
|
inputs: digests(root),
|
|
237
326
|
kind: KIND,
|
|
238
327
|
repository: expectedRepository,
|
|
239
|
-
route:
|
|
328
|
+
route: route.name,
|
|
240
329
|
runAttempt,
|
|
241
330
|
runId,
|
|
242
|
-
schemaVersion:
|
|
331
|
+
schemaVersion: SCHEMA_VERSION,
|
|
243
332
|
source: { commit: headCommit, tree: headTree },
|
|
244
333
|
workflow: WORKFLOW,
|
|
245
334
|
};
|
|
@@ -450,7 +539,7 @@ export async function downloadWorkspaceAcceptance({
|
|
|
450
539
|
}
|
|
451
540
|
|
|
452
541
|
// Declining reuse is always safe: the complete verification lane runs. Reuse
|
|
453
|
-
// is claimed only when one protected
|
|
542
|
+
// is claimed only when one exact protected route, the identical reviewed tree,
|
|
454
543
|
// one successful workflow run, and one retained artifact all agree.
|
|
455
544
|
export async function resolveWorkspaceAcceptance({
|
|
456
545
|
environment,
|
|
@@ -460,14 +549,14 @@ export async function resolveWorkspaceAcceptance({
|
|
|
460
549
|
const { root, source } = rootIdentity(requested);
|
|
461
550
|
const expectedRepository = repository(environment.GITHUB_REPOSITORY);
|
|
462
551
|
const token = environment.GH_TOKEN;
|
|
552
|
+
const route = routeForProtectedPush(environment.GITHUB_REF);
|
|
463
553
|
if (
|
|
464
554
|
typeof token !== 'string' ||
|
|
465
555
|
token.length < 1 ||
|
|
466
556
|
environment.GITHUB_EVENT_NAME !== 'push' ||
|
|
467
|
-
environment.GITHUB_REF !== 'refs/heads/main' ||
|
|
468
557
|
environment.GITHUB_SHA !== source.commit
|
|
469
558
|
) {
|
|
470
|
-
throw new Error('Workspace merge lookup lacks protected-
|
|
559
|
+
throw new Error('Workspace merge lookup lacks protected-push authority.');
|
|
471
560
|
}
|
|
472
561
|
const api = environment.GITHUB_API_URL ?? 'https://api.github.com';
|
|
473
562
|
try {
|
|
@@ -480,24 +569,56 @@ export async function resolveWorkspaceAcceptance({
|
|
|
480
569
|
(pull) =>
|
|
481
570
|
pull?.merged_at &&
|
|
482
571
|
pull?.merge_commit_sha === source.commit &&
|
|
483
|
-
pull?.base?.ref ===
|
|
484
|
-
pull?.head?.ref ===
|
|
572
|
+
pull?.base?.ref === route.base &&
|
|
573
|
+
pull?.head?.ref === route.head &&
|
|
485
574
|
pull?.head?.repo?.full_name === expectedRepository,
|
|
486
575
|
);
|
|
487
576
|
if (eligible.length !== 1) {
|
|
488
577
|
return {
|
|
489
|
-
reason: \`eligible
|
|
578
|
+
reason: \`eligible \${route.name} merges: \${eligible.length}\`,
|
|
490
579
|
reused: false,
|
|
491
580
|
};
|
|
492
581
|
}
|
|
493
582
|
const pull = eligible[0];
|
|
494
583
|
const headCommit = pull.head?.sha;
|
|
495
|
-
if (
|
|
496
|
-
|
|
584
|
+
if (
|
|
585
|
+
typeof headCommit !== 'string' ||
|
|
586
|
+
!/^[a-f0-9]{40}$/u.test(headCommit)
|
|
587
|
+
) {
|
|
588
|
+
return {
|
|
589
|
+
reason: 'protected-route head commit is not exact',
|
|
590
|
+
reused: false,
|
|
591
|
+
};
|
|
497
592
|
}
|
|
498
|
-
|
|
593
|
+
const mergeParents = git(root, [
|
|
594
|
+
'rev-list',
|
|
595
|
+
'--parents',
|
|
596
|
+
'-n',
|
|
597
|
+
'1',
|
|
598
|
+
source.commit,
|
|
599
|
+
]).split(' ');
|
|
600
|
+
if (
|
|
601
|
+
mergeParents.length !== 3 ||
|
|
602
|
+
mergeParents[0] !== source.commit ||
|
|
603
|
+
mergeParents[2] !== headCommit
|
|
604
|
+
) {
|
|
499
605
|
return {
|
|
500
|
-
reason: '
|
|
606
|
+
reason: 'protected-route merge parents are not exact',
|
|
607
|
+
reused: false,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
const baseCommit = mergeParents[1];
|
|
611
|
+
const baseTree = git(root, ['rev-parse', \`\${baseCommit}^{tree}\`]);
|
|
612
|
+
const headTree = git(root, ['rev-parse', \`\${headCommit}^{tree}\`]);
|
|
613
|
+
if (headTree !== source.tree) {
|
|
614
|
+
return {
|
|
615
|
+
reason: 'merged tree differs from the reviewed protected-route tree',
|
|
616
|
+
reused: false,
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
if (route.historyOnly && baseTree !== headTree) {
|
|
620
|
+
return {
|
|
621
|
+
reason: 'protected-main-sync changes protected source',
|
|
501
622
|
reused: false,
|
|
502
623
|
};
|
|
503
624
|
}
|
|
@@ -518,7 +639,7 @@ export async function resolveWorkspaceAcceptance({
|
|
|
518
639
|
run?.conclusion === 'success' &&
|
|
519
640
|
run?.event === 'pull_request' &&
|
|
520
641
|
run?.head_sha === headCommit &&
|
|
521
|
-
run?.head_branch ===
|
|
642
|
+
run?.head_branch === route.head &&
|
|
522
643
|
run?.head_repository?.full_name === expectedRepository &&
|
|
523
644
|
run?.path === WORKFLOW &&
|
|
524
645
|
Number.isSafeInteger(run.id) &&
|
|
@@ -559,15 +680,19 @@ export async function resolveWorkspaceAcceptance({
|
|
|
559
680
|
artifactId: id,
|
|
560
681
|
artifactName,
|
|
561
682
|
artifactSize: size,
|
|
683
|
+
baseCommit,
|
|
562
684
|
headCommit,
|
|
685
|
+
historyOnly: route.historyOnly,
|
|
563
686
|
reused: true,
|
|
687
|
+
route: route.name,
|
|
564
688
|
runAttempt: String(run.run_attempt),
|
|
565
689
|
runId: String(run.id),
|
|
566
690
|
};
|
|
567
691
|
}
|
|
568
692
|
}
|
|
569
693
|
return {
|
|
570
|
-
reason:
|
|
694
|
+
reason:
|
|
695
|
+
'no successful protected-route run retains the acceptance artifact',
|
|
571
696
|
reused: false,
|
|
572
697
|
};
|
|
573
698
|
} catch (error) {
|
|
@@ -581,21 +706,33 @@ export async function resolveWorkspaceAcceptance({
|
|
|
581
706
|
async function main(argv) {
|
|
582
707
|
const [operation, ...args] = argv;
|
|
583
708
|
if (operation === 'seal' && args.length === 1) {
|
|
584
|
-
sealWorkspaceAcceptance({
|
|
709
|
+
const result = sealWorkspaceAcceptance({
|
|
585
710
|
environment: process.env,
|
|
586
711
|
output: path.resolve(args[0]),
|
|
587
712
|
root: process.cwd(),
|
|
588
713
|
});
|
|
714
|
+
const output = process.env.GITHUB_OUTPUT;
|
|
715
|
+
if (typeof output !== 'string' || !path.isAbsolute(output)) {
|
|
716
|
+
throw new Error('Workspace acceptance output authority is missing.');
|
|
717
|
+
}
|
|
718
|
+
appendFileSync(output, \`sealed=\${String(result.sealed !== false)}\\n\`, 'utf8');
|
|
719
|
+
if (result.sealed === false) {
|
|
720
|
+
console.log(
|
|
721
|
+
\`::warning title=Protected sync evidence declined::\${result.reason}; no reusable acceptance artifact was sealed.\`,
|
|
722
|
+
);
|
|
723
|
+
}
|
|
589
724
|
return;
|
|
590
725
|
}
|
|
591
|
-
if (operation === 'verify' && args.length ===
|
|
726
|
+
if (operation === 'verify' && args.length === 6) {
|
|
592
727
|
verifyWorkspaceAcceptance({
|
|
728
|
+
baseCommit: args[2],
|
|
593
729
|
headCommit: args[1],
|
|
594
730
|
manifestPath: path.resolve(args[0]),
|
|
595
731
|
repository: process.env.GITHUB_REPOSITORY,
|
|
596
732
|
root: process.cwd(),
|
|
597
|
-
|
|
598
|
-
|
|
733
|
+
route: args[3],
|
|
734
|
+
runAttempt: args[5],
|
|
735
|
+
runId: args[4],
|
|
599
736
|
});
|
|
600
737
|
return;
|
|
601
738
|
}
|
|
@@ -628,8 +765,11 @@ async function main(argv) {
|
|
|
628
765
|
artifact_id: result.artifactId ?? '',
|
|
629
766
|
artifact_name: result.artifactName ?? '',
|
|
630
767
|
artifact_size: result.artifactSize ?? '',
|
|
768
|
+
base_commit: result.baseCommit ?? '',
|
|
631
769
|
head_commit: result.headCommit ?? '',
|
|
770
|
+
history_only: String(result.historyOnly === true),
|
|
632
771
|
reused: String(result.reused),
|
|
772
|
+
route: result.route ?? '',
|
|
633
773
|
run_attempt: result.runAttempt ?? '',
|
|
634
774
|
run_id: result.runId ?? '',
|
|
635
775
|
})) {
|
|
@@ -638,7 +778,7 @@ async function main(argv) {
|
|
|
638
778
|
return;
|
|
639
779
|
}
|
|
640
780
|
throw new Error(
|
|
641
|
-
'Usage: workspace-acceptance.mjs seal <manifest> | download <output> <artifact-id> <artifact-digest> <artifact-size> | verify <manifest> <head> <run> <attempt> | resolve',
|
|
781
|
+
'Usage: workspace-acceptance.mjs seal <manifest> | download <output> <artifact-id> <artifact-digest> <artifact-size> | verify <manifest> <head> <base> <route> <run> <attempt> | resolve',
|
|
642
782
|
);
|
|
643
783
|
}
|
|
644
784
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-files-ci-acceptance.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/preset/workspace-files-ci-acceptance.ts"],"names":[],"mappings":";;AAAA,
|
|
1
|
+
{"version":3,"file":"workspace-files-ci-acceptance.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/preset/workspace-files-ci-acceptance.ts"],"names":[],"mappings":";;AAAA,4EAoxBC;AApxBD,SAAgB,gCAAgC;IAG9C,OAAO;QACL,mCAAmC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8wBxC;KACE,CAAC;AACJ,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { DeploymentProfile } from '../../repository-policy/index.js';
|
|
1
2
|
export declare const DEVELOPER_AGENT_RUNBOOK_PATH: "docs/developer-agent.md";
|
|
2
3
|
export declare const DEVELOPER_AGENT_HANDOFF_TEMPLATE_PATH: "docs/developer-agent-handoff.template.json";
|
|
3
4
|
export declare const DEVELOPER_AGENT_ADAPTER_EVALUATION_PATH: "docs/developer-agent-adapters.md";
|
|
4
5
|
export declare const DEVELOPER_AGENT_WORKSPACE_SEEDED_PATHS: readonly ["docs/developer-agent.md", "docs/developer-agent-handoff.template.json", "docs/developer-agent-adapters.md"];
|
|
5
6
|
export interface DeveloperAgentWorkspaceFileOptions {
|
|
7
|
+
deploymentProfile: DeploymentProfile;
|
|
6
8
|
frameworkVersion: string;
|
|
7
9
|
name: string;
|
|
8
10
|
}
|