Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
6 changes: 3 additions & 3 deletions .github/workflows/appguardrail.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
scan:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
actions: read
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
compose_runtime:
Expand Down Expand Up @@ -49,7 +49,7 @@ jobs:
>/dev/null

today-concurrency:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 10
env:
PLANNING_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/life_os_test
Expand Down Expand Up @@ -92,7 +92,7 @@ jobs:

validate:
needs: compose_runtime
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 20
env:
AI_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/life_os_test
Expand Down Expand Up @@ -175,7 +175,7 @@ jobs:
run: docker compose config --quiet

browser-acceptance:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout exact contributor head
Expand Down Expand Up @@ -203,7 +203,7 @@ jobs:

merge_compatibility:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 20
env:
AI_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/life_os_test
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/commercial-readiness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.repository }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
EVIDENCE_DIR: commercial-readiness-evidence

jobs:
audit:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
actions: read
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
github.event_name != 'pull_request'
&& github.ref == 'refs/heads/main'
needs: audit
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
actions: read
Expand Down Expand Up @@ -146,7 +146,7 @@ jobs:
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
&& github.ref == 'refs/heads/main'
needs: [audit, publish]
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 20
permissions:
actions: read
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ env:
jobs:
validate:
name: Validate immutable deployment
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout exact revision
Expand Down Expand Up @@ -75,7 +75,7 @@ jobs:
deploy:
name: Apply protected production rollout
needs: validate
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 30
environment: production
env:
Expand Down
68 changes: 60 additions & 8 deletions packages/commercial-readiness/src/workflow-contract.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,25 @@ describe('commercial readiness workflow contract', () => {
assert.match(workflow, /github\.ref == 'refs\/heads\/main'/);
});

it('isolates scheduled drains from push-triggered publication runs', async () => {
const workflow = await repositoryFile(
it('cancels only superseded heads from the same pull request', async () => {
const paths = [
'.github/workflows/appguardrail.yml',
'.github/workflows/ci.yml',
'.github/workflows/commercial-readiness.yml',
);
assert.match(
workflow,
/group:\s*\$\{\{ github\.workflow \}\}-\$\{\{ github\.event_name \}\}-/,
);
assert.match(workflow, /cancel-in-progress:\s*true/);
];
for (const path of paths) {
const workflow = await repositoryFile(path);
assert.match(
workflow,
/group:\s*\$\{\{ github\.workflow \}\}-\$\{\{ github\.repository \}\}-\$\{\{ github\.event_name == 'pull_request' && github\.event\.pull_request\.number \|\| github\.run_id \}\}/,
path,
);
assert.match(
workflow,
/cancel-in-progress:\s*\$\{\{ github\.event_name == 'pull_request' \}\}/,
path,
);
}
});

it('pins every external action to a full commit SHA and retains evidence for no more than seven days', async () => {
Expand Down Expand Up @@ -95,6 +105,48 @@ describe('commercial readiness workflow contract', () => {
);
});

it('pins every LifeOS-owned hosted-runner workflow to the explicit supported Ubuntu image', async () => {
const ciWorkflow = await repositoryFile('.github/workflows/ci.yml');
const ciJobs = [
'compose_runtime',
'today-concurrency',
'validate',
'browser-acceptance',
'merge_compatibility',
];

for (const job of ciJobs) {
assert.match(
yamlJobBlock(ciWorkflow, job),
/^\s+runs-on:\s*ubuntu-24\.04\s*$/mu,
`${job} must use the explicit supported GitHub-hosted runner image`,
);
}

const hostedRunnerWorkflows = [
'.github/workflows/ai-proposal-live-conformance.yml',
'.github/workflows/appguardrail.yml',
'.github/workflows/ci.yml',
'.github/workflows/commercial-readiness.yml',
'.github/workflows/deploy.yml',
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
'.github/workflows/opencode-commercial-development.yml',
];
Comment thread
seonghobae marked this conversation as resolved.
for (const path of hostedRunnerWorkflows) {
const workflow = await repositoryFile(path);
const runners = [...workflow.matchAll(/^\s+runs-on:\s*(\S+)\s*$/gmu)].map(
([, runner]) => runner,
);
assert.ok(runners.length > 0, `${path} must define a hosted runner`);
for (const runner of runners) {
assert.equal(
runner,
'ubuntu-24.04',
`${path} must use ubuntu-24.04 for every hosted runner job`,
);
}
}
});

it('requires all review and security gates before merge mode can execute', async () => {
const policy = JSON.parse(
await repositoryFile('product/commercial-readiness-policy.json'),
Expand Down
Loading