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
21 changes: 15 additions & 6 deletions .github/workflows/cli-package-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [main]
paths:
- '.github/workflows/cli-package-validation.yml'
- '.github/workflows/release-cli-*.yml'
- '.gitattributes'
- '.npmrc'
- 'LICENSE'
Expand Down Expand Up @@ -32,6 +33,7 @@ on:
branches: [main]
paths:
- '.github/workflows/cli-package-validation.yml'
- '.github/workflows/release-cli-*.yml'
- '.gitattributes'
- '.npmrc'
- 'LICENSE'
Expand All @@ -56,6 +58,10 @@ on:
- 'scripts/smoke-release-cli-package.mjs'
- 'tsconfig*.json'
workflow_call:
outputs:
release_candidate_artifact_id:
description: Immutable artifact produced by the build job
value: ${{ jobs.build.outputs.release_candidate_artifact_id }}
workflow_dispatch:

permissions:
Expand All @@ -70,6 +76,8 @@ jobs:
name: Build immutable tarball
runs-on: ubuntu-24.04
timeout-minutes: 60
outputs:
release_candidate_artifact_id: ${{ steps.release-candidate.outputs.artifact-id }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -79,13 +87,14 @@ jobs:
node-version: '22.19.0'
cache: npm
- name: Select the release npm toolchain
run: npm install --global --no-audit --no-fund npm@11.12.1
run: npm install --global --no-audit --no-fund "$(node -p 'require("./package.json").packageManager')"
- name: Build the release tarball once
run: npm run release:cli:pack
- name: Upload the immutable release candidate
id: release-candidate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cli-release-candidate
name: cli-release-candidate-${{ github.run_attempt }}
path: |
packages/cli/release/*.tgz
packages/cli/release/*.tgz.sha256
Expand Down Expand Up @@ -130,7 +139,7 @@ jobs:
with:
node-version: ${{ matrix.node }}
- name: Select the release npm toolchain
run: npm install --global --no-audit --no-fund npm@11.12.1
run: npm install --global --no-audit --no-fund "$(node -p 'require("./package.json").packageManager')"
- name: Assert the runner architecture
env:
EXPECTED_PLATFORM: ${{ matrix.platform }}
Expand All @@ -140,7 +149,7 @@ jobs:
- name: Download the release candidate
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: cli-release-candidate
artifact-ids: ${{ needs.build.outputs.release_candidate_artifact_id }}
path: packages/cli/release
- name: Validate the installed tarball
run: node scripts/smoke-release-cli-package.mjs
Expand All @@ -161,7 +170,7 @@ jobs:
with:
python-version: '3.12'
- name: Select the release npm toolchain
run: npm install --global --no-audit --no-fund npm@11.12.1
run: npm install --global --no-audit --no-fund "$(node -p 'require("./package.json").packageManager')"
- name: Install pinned Eval frameworks
run: |
python -m venv "$RUNNER_TEMP/maka-harbor"
Expand All @@ -173,7 +182,7 @@ jobs:
- name: Download the release candidate
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: cli-release-candidate
artifact-ids: ${{ needs.build.outputs.release_candidate_artifact_id }}
path: packages/cli/release
- name: Validate real Harbor and Pier cells
run: npm run release:cli:eval
198 changes: 198 additions & 0 deletions .github/workflows/release-cli-finalize.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
name: Finalize CLI npm release

on:
workflow_dispatch:
inputs:
stage_run_id:
description: Successful Stage CLI npm release workflow run ID
required: true
type: string
stage_run_attempt:
description: Successful Stage CLI npm release workflow run attempt
required: true
type: string
version:
description: Exact staged maka-agent version
required: true
type: string

permissions:
actions: read
contents: read

concurrency:
group: cli-npm-finalize
cancel-in-progress: false

jobs:
inspect:
name: Verify the public npm release
runs-on: ubuntu-24.04
timeout-minutes: 20
outputs:
dist_tag: ${{ steps.release.outputs.dist_tag }}
git_tag: ${{ steps.release.outputs.git_tag }}
public_release_artifact_id: ${{ steps.public-release.outputs.artifact-id }}
source_sha: ${{ steps.release.outputs.source_sha }}
tarball: ${{ steps.release.outputs.tarball }}
version: ${{ steps.release.outputs.version }}
steps:
- name: Require main
env:
RELEASE_REF: ${{ github.ref }}
run: |
if [[ "$RELEASE_REF" != "refs/heads/main" ]]; then
echo "CLI releases must be dispatched from main; found $RELEASE_REF" >&2
exit 1
fi
- name: Load the exact stage workflow run
id: stage-run
env:
GH_TOKEN: ${{ github.token }}
STAGE_RUN_ID: ${{ inputs.stage_run_id }}
STAGE_RUN_ATTEMPT: ${{ inputs.stage_run_attempt }}
run: |
if [[ ! "$STAGE_RUN_ID" =~ ^[1-9][0-9]*$ ]]; then
echo "Stage workflow run ID must be a positive integer" >&2
exit 1
fi
if [[ ! "$STAGE_RUN_ATTEMPT" =~ ^[1-9][0-9]*$ ]]; then
echo "Stage workflow run attempt must be a positive integer" >&2
exit 1
fi
gh api "repos/$GITHUB_REPOSITORY/actions/runs/$STAGE_RUN_ID/attempts/$STAGE_RUN_ATTEMPT" > "$RUNNER_TEMP/stage-run.json"
node -e '
const fs = require("node:fs");
const run = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
if (
String(run.id) !== process.env.STAGE_RUN_ID ||
String(run.run_attempt) !== process.env.STAGE_RUN_ATTEMPT ||
run.path !== ".github/workflows/release-cli-stage.yml" ||
run.event !== "workflow_dispatch" ||
run.head_branch !== "main" ||
run.conclusion !== "success" ||
run.head_repository?.full_name !== process.env.GITHUB_REPOSITORY
) {
throw new Error("Stage run is not an exact successful main CLI stage attempt");
}
if (!/^[0-9a-f]{40}$/.test(run.head_sha)) throw new Error("Stage run has no valid source SHA");
fs.appendFileSync(process.env.GITHUB_OUTPUT, "source_sha=" + run.head_sha + "\n");
' "$RUNNER_TEMP/stage-run.json"
- name: Check out the current release verifier
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
package-manager-cache: false
- name: Select the release npm toolchain
run: npm install --global --no-audit --no-fund "$(node -p 'require("./package.json").packageManager')"
- name: Download the exact staged candidate
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: cli-staged-release-${{ inputs.stage_run_attempt }}
path: packages/cli/release
github-token: ${{ github.token }}
repository: ${{ github.repository }}
run-id: ${{ inputs.stage_run_id }}
- name: Verify the stage run and release record
id: release
env:
EXPECTED_VERSION: ${{ inputs.version }}
run: |
node scripts/release-cli-publication.mjs validate-stage-run \
packages/cli/release \
"$RUNNER_TEMP/stage-run.json" \
"$EXPECTED_VERSION" \
"$GITHUB_OUTPUT"
- name: Fetch and verify the public registry bytes
run: |
node scripts/release-cli-publication.mjs fetch-registry \
packages/cli/release \
"$RUNNER_TEMP/registry-release"
- name: Verify npm signatures and provenance
run: |
node scripts/release-cli-publication.mjs prepare-audit \
packages/cli/release \
"$RUNNER_TEMP/signature-audit"
cd "$RUNNER_TEMP/signature-audit"
npm audit signatures --json --include-attestations > audit.json
node "$GITHUB_WORKSPACE/scripts/release-cli-publication.mjs" validate-audit \
"$GITHUB_WORKSPACE/packages/cli/release" \
"$RUNNER_TEMP/signature-audit/audit.json"
- name: Preserve the verified public release
id: public-release
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cli-public-release-${{ github.run_attempt }}
path: ${{ runner.temp }}/registry-release
if-no-files-found: error
compression-level: 0
retention-days: 30

publish:
name: Create the GitHub CLI release
needs: inspect
runs-on: ubuntu-24.04
timeout-minutes: 10
environment:
name: npm-release
url: https://github.com/maka-agent/maka-agent/releases/tag/${{ needs.inspect.outputs.git_tag }}
permissions:
contents: write
steps:
- name: Download the verified public release
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
artifact-ids: ${{ needs.inspect.outputs.public_release_artifact_id }}
path: ${{ runner.temp }}/registry-release
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
- name: Create the Git tag and GitHub Release
env:
GH_TOKEN: ${{ github.token }}
RELEASE_DIST_TAG: ${{ needs.inspect.outputs.dist_tag }}
RELEASE_DIRECTORY: ${{ runner.temp }}/registry-release
RELEASE_SHA: ${{ needs.inspect.outputs.source_sha }}
RELEASE_TAG: ${{ needs.inspect.outputs.git_tag }}
RELEASE_TARBALL_NAME: ${{ needs.inspect.outputs.tarball }}
RELEASE_VERSION: ${{ needs.inspect.outputs.version }}
run: |
tag_json="$RUNNER_TEMP/release-tag.json"
tag_ref="repos/$GITHUB_REPOSITORY/git/ref/tags/$RELEASE_TAG"
if ! gh api "$tag_ref" > "$tag_json" 2>/dev/null; then
if ! gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \
-f ref="refs/tags/$RELEASE_TAG" \
-f sha="$RELEASE_SHA" > "$tag_json"; then
gh api "$tag_ref" > "$tag_json"
fi
fi
TAG_JSON="$tag_json" node -e '
const fs = require("node:fs");
const tag = JSON.parse(fs.readFileSync(process.env.TAG_JSON, "utf8"));
if (
tag.ref !== "refs/tags/" + process.env.RELEASE_TAG ||
tag.object?.type !== "commit" ||
tag.object.sha !== process.env.RELEASE_SHA
) {
throw new Error("Git tag does not point to the verified CLI release commit");
}
'

release_flags=(--latest=false)
if [[ "$RELEASE_DIST_TAG" == "next" ]]; then
release_flags+=(--prerelease)
elif [[ "$RELEASE_DIST_TAG" != "latest" ]]; then
echo "Unsupported CLI release dist-tag: $RELEASE_DIST_TAG" >&2
exit 1
fi
gh release create "$RELEASE_TAG" \
"$RELEASE_DIRECTORY/$RELEASE_TARBALL_NAME" \
"$RELEASE_DIRECTORY/$RELEASE_TARBALL_NAME.sha256" \
"$RELEASE_DIRECTORY/$RELEASE_TARBALL_NAME.files.json" \
"$RELEASE_DIRECTORY/release.json" \
--repo "$GITHUB_REPOSITORY" \
--verify-tag \
"${release_flags[@]}" \
--title "Maka CLI $RELEASE_VERSION" \
--notes-file "$RELEASE_DIRECTORY/release-notes.md"
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
Comment thread
M4n5ter marked this conversation as resolved.
Loading
Loading