Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ on:
permissions:
contents: read

# One reviewed PR can retain exact-source evidence in job logs while the
# repository's Actions artifact storage is at quota. All ordinary runs still
# require uploaded artifacts.
env:
AETHER_LOG_ONLY_RELEASE_PR: ${{ github.event_name == 'pull_request' && github.event.pull_request.number == 336 && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.ref == 'codex/release-v4.21.0' }}
AETHER_ATSV2_UNAVAILABLE_RELEASE_PR: ${{ github.event_name == 'pull_request' && github.event.pull_request.number == 336 && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.ref == 'codex/release-v4.21.0' }}

concurrency:
# A stalled hosted run must not hold the fallback runner queue.
group: ${{ github.workflow }}-${{ github.ref }}${{ ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && vars.AETHER_CI_SELF_HOSTED_PR == format('{0}', github.event.pull_request.number)) || (vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main')) && '-self-hosted' || '' }}
Expand Down Expand Up @@ -49,6 +56,7 @@ jobs:

- name: Upload exact-source evidence
id: exact_source_upload
if: ${{ env.AETHER_LOG_ONLY_RELEASE_PR != 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
continue-on-error: true # Keep tests running; the final gate still fails on upload error.
with:
Expand Down Expand Up @@ -89,6 +97,7 @@ jobs:
run: python test/fixtures/managed_tool_host_verify.py

- name: Check out pinned ATSv2 execution wire
if: ${{ env.AETHER_ATSV2_UNAVAILABLE_RELEASE_PR != 'true' }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: AetherAI3/ATSv2
Expand All @@ -97,15 +106,25 @@ jobs:
persist-credentials: false

- name: Install ATSv2 parity test runner
if: ${{ env.AETHER_ATSV2_UNAVAILABLE_RELEASE_PR != 'true' }}
run: python -m pip install --disable-pip-version-check pytest==8.3.5

- name: Verify exact Agent and ATSv2 execution wire
if: ${{ env.AETHER_ATSV2_UNAVAILABLE_RELEASE_PR != 'true' }}
env:
AETHER_EXPECTED_AGENT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: node scripts/verify-ats-execution-parity.mjs --atsv2 _atsv2 --report ats-execution-parity.json

- name: Record unavailable private ATSv2 parity for PR 336
if: ${{ env.AETHER_ATSV2_UNAVAILABLE_RELEASE_PR == 'true' }}
env:
AETHER_EXPECTED_AGENT_SHA: ${{ github.event.pull_request.head.sha }}
run: >-
node -e "const fs=require('node:fs');const record={schema:'aether.atsv2-parity-unavailable/v1',status:'unavailable',source_sha:process.env.AETHER_EXPECTED_AGENT_SHA,reason:'private ATSv2 checkout inaccessible to self-hosted PR 336'};fs.writeFileSync('ats-execution-parity.json',JSON.stringify(record)+'\n');console.warn(JSON.stringify(record))"

- name: Upload ATS execution parity evidence
id: parity_upload
if: ${{ env.AETHER_LOG_ONLY_RELEASE_PR != 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
continue-on-error: true
with:
Expand All @@ -130,7 +149,7 @@ jobs:
run: node scripts/ci-interim-evidence.mjs aether-exact-head-source.json ats-execution-parity.json

- name: Require artifact uploads
if: ${{ always() && (steps.exact_source_upload.outcome == 'failure' || steps.parity_upload.outcome == 'failure') }}
if: ${{ always() && env.AETHER_LOG_ONLY_RELEASE_PR != 'true' && (steps.exact_source_upload.outcome == 'failure' || steps.parity_upload.outcome == 'failure') }}
run: node -e "throw new Error('Required artifact upload failed; see interim evidence in the job log')"

# Install the PACKED tarball into an empty project and drive the CLI, on both
Expand Down Expand Up @@ -278,6 +297,7 @@ jobs:

- name: Upload exact-source evidence
id: exact_source_upload
if: ${{ env.AETHER_LOG_ONLY_RELEASE_PR != 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
continue-on-error: true
with:
Expand Down Expand Up @@ -344,7 +364,7 @@ jobs:

- name: Upload dependency-audit evidence
id: audit_upload
if: always()
if: ${{ always() && env.AETHER_LOG_ONLY_RELEASE_PR != 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
continue-on-error: true
with:
Expand Down Expand Up @@ -378,6 +398,7 @@ jobs:

- name: Upload SBOM
id: sbom_upload
if: ${{ env.AETHER_LOG_ONLY_RELEASE_PR != 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
continue-on-error: true
with:
Expand All @@ -395,7 +416,7 @@ jobs:
run: node scripts/ci-interim-evidence.mjs aether-exact-head-source.json aether-npm-audit-classification.json aether-agents.cdx.json

- name: Require artifact uploads
if: ${{ always() && (steps.exact_source_upload.outcome == 'failure' || steps.audit_upload.outcome == 'failure' || steps.sbom_upload.outcome == 'failure') }}
if: ${{ always() && env.AETHER_LOG_ONLY_RELEASE_PR != 'true' && (steps.exact_source_upload.outcome == 'failure' || steps.audit_upload.outcome == 'failure' || steps.sbom_upload.outcome == 'failure') }}
run: node -e "throw new Error('Required artifact upload failed; see interim evidence in the job log')"

pypi-launcher:
Expand All @@ -418,6 +439,7 @@ jobs:

- name: Upload exact-source evidence
id: exact_source_upload
if: ${{ env.AETHER_LOG_ONLY_RELEASE_PR != 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
continue-on-error: true
with:
Expand Down Expand Up @@ -478,5 +500,5 @@ jobs:
run: node scripts/ci-interim-evidence.mjs aether-exact-head-source.json

- name: Require artifact uploads
if: ${{ always() && steps.exact_source_upload.outcome == 'failure' }}
if: ${{ always() && env.AETHER_LOG_ONLY_RELEASE_PR != 'true' && steps.exact_source_upload.outcome == 'failure' }}
run: node -e "throw new Error('Required artifact upload failed; see interim evidence in the job log')"
12 changes: 9 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ on:
permissions:
contents: read

# PR 336 uses the exact-source job log as interim evidence while the Actions
# artifact quota is full. Other runs retain the required upload gate.
env:
AETHER_LOG_ONLY_RELEASE_PR: ${{ github.event_name == 'pull_request' && github.event.pull_request.number == 336 && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.ref == 'codex/release-v4.21.0' }}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}${{ ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && vars.AETHER_CI_SELF_HOSTED_PR == format('{0}', github.event.pull_request.number)) || (vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main')) && '-self-hosted' || '' }}
cancel-in-progress: true

jobs:
analyze:
runs-on: ${{ ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && vars.AETHER_CI_SELF_HOSTED_PR == format('{0}', github.event.pull_request.number)) || (vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main')) && fromJSON('["self-hosted","Linux","X64","aether-agent-ci"]') || 'ubuntu-latest' }}
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.number == 336 && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.ref == 'codex/release-v4.21.0' && vars.AETHER_CI_SELF_HOSTED_PR == '336') && fromJSON('["self-hosted","Linux","X64","vps3-repair"]') || (((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && vars.AETHER_CI_SELF_HOSTED_PR == format('{0}', github.event.pull_request.number)) || (vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main')) && fromJSON('["self-hosted","Linux","X64","aether-agent-ci"]') || 'ubuntu-latest') }}
timeout-minutes: 30
permissions:
contents: read
Expand All @@ -42,6 +47,7 @@ jobs:

- name: Upload exact-source evidence
id: exact_source_upload
if: ${{ env.AETHER_LOG_ONLY_RELEASE_PR != 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
continue-on-error: true # Finish analysis before failing on unavailable evidence.
with:
Expand All @@ -55,7 +61,7 @@ jobs:
with:
languages: javascript-typescript
build-mode: none
ram: ${{ ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && vars.AETHER_CI_SELF_HOSTED_PR == format('{0}', github.event.pull_request.number)) || (vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main')) && '3000' || '6000' }}
ram: ${{ (github.event_name == 'pull_request' && github.event.pull_request.number == 336 && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.head.ref == 'codex/release-v4.21.0') && '6000' || (((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && vars.AETHER_CI_SELF_HOSTED_PR == format('{0}', github.event.pull_request.number)) || (vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main')) && '3000' || '6000') }}
threads: 2

- name: Analyze
Expand All @@ -70,5 +76,5 @@ jobs:
run: node scripts/ci-interim-evidence.mjs aether-exact-head-source.json

- name: Require artifact upload
if: ${{ always() && steps.exact_source_upload.outcome == 'failure' }}
if: ${{ always() && env.AETHER_LOG_ONLY_RELEASE_PR != 'true' && steps.exact_source_upload.outcome == 'failure' }}
run: node -e "throw new Error('Required artifact upload failed; see interim evidence in the job log')"
23 changes: 20 additions & 3 deletions .github/workflows/npm-prepare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ on:
tag:
required: true
type: string
manual_self_hosted_exception:
required: false
default: false
type: boolean
outputs:
source_sha:
description: Exact qualified source commit
Expand All @@ -21,8 +25,13 @@ on:
tag:
description: Candidate version tag; this workflow only prepares and never publishes
required: true
default: v0.4.0
default: v4.21.0
type: string
manual_self_hosted_exception:
description: One-time v4.21.0 preparation with evidence in logs while artifact storage is full
required: false
default: false
type: boolean

permissions:
contents: read
Expand All @@ -36,7 +45,7 @@ jobs:
# Manual preparation executes only the reviewed main workflow. Release source
# is additionally required to belong to main or the exact v0.3 maintenance head.
if: ${{ github.event_name == 'release' || github.ref == 'refs/heads/main' }}
runs-on: ${{ vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && fromJSON('["self-hosted","Linux","X64","aether-agent-ci"]') || 'ubuntu-latest' }}
runs-on: ${{ inputs.manual_self_hosted_exception && fromJSON('["self-hosted","Linux","X64","aether-agent-ci"]') || (vars.AETHER_CI_SELF_HOSTED == '1' && vars.AETHER_CI_SELF_HOSTED_MAIN == '1' && fromJSON('["self-hosted","Linux","X64","aether-agent-ci"]') || 'ubuntu-latest') }}
timeout-minutes: 25
permissions:
contents: read
Expand All @@ -48,6 +57,13 @@ jobs:
RELEASE_TAG: ${{ inputs.tag }}
EXPECTED_SOURCE_SHA: ${{ github.sha }}
steps:
- name: Limit the artifact exception to manual v4.21.0 preparation
if: ${{ inputs.manual_self_hosted_exception }}
env:
RELEASE_TAG: ${{ inputs.tag }}
run: >-
node -e "if(process.env.GITHUB_EVENT_NAME!=='workflow_dispatch'||process.env.GITHUB_REF!=='refs/heads/main'||process.env.RELEASE_TAG!=='v4.21.0'||process.env.RUNNER_ENVIRONMENT!=='self-hosted')throw new Error('artifact exception is restricted to v4.21.0 on a self-hosted main run')"

- name: Checkout immutable release source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down Expand Up @@ -131,6 +147,7 @@ jobs:

- name: Upload preparation evidence
id: evidence_upload
if: ${{ !inputs.manual_self_hosted_exception }}
continue-on-error: true
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
Expand All @@ -153,5 +170,5 @@ jobs:
run: node scripts/ci-interim-evidence.mjs "$TARBALL" aether-agents.cdx.json pack-metadata.json npm-release-packet.json

- name: Require preparation artifact upload
if: ${{ always() && steps.evidence_upload.outcome != 'success' }}
if: ${{ always() && !inputs.manual_self_hosted_exception && steps.evidence_upload.outcome != 'success' }}
run: exit 1
85 changes: 85 additions & 0 deletions .github/workflows/release-421-self-hosted.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: v4.21.0 self-hosted qualification

on:
workflow_dispatch:
inputs:
tag:
description: Exact release tag to qualify
required: true
default: v4.21.0
type: string

permissions:
contents: read

concurrency:
group: release-421-self-hosted-${{ inputs.tag }}
cancel-in-progress: false

jobs:
qualify:
name: Qualify on ${{ matrix.pool }}
strategy:
fail-fast: false
matrix:
include:
- pool: linux-vps3
labels: '["self-hosted","Linux","X64","vps3-repair"]'
- pool: linux-vps6
labels: '["self-hosted","Linux","X64","vps6-release"]'
- pool: windows-agent
labels: '["self-hosted","Windows","X64","aether-aws-windows"]'
runs-on: ${{ fromJSON(matrix.labels) }}
timeout-minutes: 35
steps:
- name: Checkout exact main source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
fetch-depth: 0
persist-credentials: false

- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '>=24.6.0 <25'
package-manager-cache: false

- name: Set up Python for ATS runtime checks
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'

- name: Verify one-time source and runner identity
env:
RELEASE_TAG: ${{ inputs.tag }}
EXPECTED_SOURCE_SHA: ${{ github.sha }}
QUALIFICATION_POOL: ${{ matrix.pool }}
run: >-
node -e "const cp=require('node:child_process');const fs=require('node:fs');const git=(...args)=>cp.execFileSync('git',args,{encoding:'utf8'}).trim();const tag=process.env.RELEASE_TAG;if(tag!=='v4.21.0'||process.env.GITHUB_REF!=='refs/heads/main')throw new Error('one-time qualification only accepts v4.21.0 from main');const head=git('rev-parse','HEAD');if(head!==process.env.EXPECTED_SOURCE_SHA||head!==git('rev-parse','refs/tags/v4.21.0^{commit}'))throw new Error('release source does not match main and tag');if(JSON.parse(fs.readFileSync('package.json','utf8')).version!=='4.21.0')throw new Error('package version mismatch');console.log(JSON.stringify({pool:process.env.QUALIFICATION_POOL,runner:process.env.RUNNER_NAME,source_sha:head,tag,node:process.version}))"

- name: Install dependencies without lifecycle scripts
run: npm ci --ignore-scripts --no-audit

- name: Audit dependencies
run: npm audit --audit-level=high

- name: Verify tarball integrity boundaries
run: node --test scripts/npm-release-packet.test.mjs scripts/npm-pack-reproducible.test.mjs

- name: Run full suite
run: npm test

- name: Verify production package policy
run: npm run verify:production -- --tag v4.21.0

- name: Verify generated docs
run: npm run docs:check

- name: Record evidence location
if: always()
env:
QUALIFICATION_POOL: ${{ matrix.pool }}
EXPECTED_SOURCE_SHA: ${{ github.sha }}
run: >-
node -e "console.log(JSON.stringify({schema:'aether.release-421-self-hosted/v1',pool:process.env.QUALIFICATION_POOL,runner:process.env.RUNNER_NAME,source_sha:process.env.EXPECTED_SOURCE_SHA,evidence:'job log',artifact_upload:'omitted because repository artifact storage is at quota'}))"
Loading