Spaces:
Running
Running
Download .github/workflows/release.yaml from Leon4gr45/brain: direct link, hf CLI and curl.
- Browser
- Download file 5.95 kB
-
https://huggingface.co/spaces/Leon4gr45/brain/resolve/main/.github/workflows/release.yaml
- Command line
-
hf download hf://spaces/Leon4gr45/brain/.github/workflows/release.yaml
-
curl -L -o release.yaml https://huggingface.co/spaces/Leon4gr45/brain/resolve/main/.github/workflows/release.yaml
5.95 kB
| name: Publish tagged container | |
| on: | |
| push: | |
| tags: ["v*"] | |
| permissions: | |
| contents: read | |
| checks: read | |
| actions: read | |
| packages: write | |
| id-token: write | |
| jobs: | |
| validate-tag: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.tag.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - id: tag | |
| run: python scripts/release_version.py "$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT" | |
| - name: Require tag version to match project metadata | |
| run: | | |
| project_version=$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])') | |
| expected_version="${{ steps.tag.outputs.project_version }}" | |
| test "$project_version" = "$expected_version" | |
| - name: Require the tagged commit to be on main | |
| run: git merge-base --is-ancestor "$GITHUB_SHA" origin/main | |
| verify-required-checks: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Require successful quality and heavy validation for this commit | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const required = [ | |
| "python", | |
| "benchmark-helpers", | |
| "frontend (console)", | |
| "frontend (tui)", | |
| "rust", | |
| "image-light-smoke", | |
| "heavy-smoke-and-restore", | |
| ]; | |
| const runs = await github.paginate(github.rest.checks.listForRef, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| ref: context.sha, | |
| per_page: 100, | |
| }); | |
| const failed = required.filter((name) => | |
| !runs.some((run) => run.name === name && run.conclusion === "success") | |
| ); | |
| if (failed.length) { | |
| core.setFailed(`Missing successful checks for ${context.sha}: ${failed.join(", ")}`); | |
| } | |
| - name: Download exact-commit validation artifacts | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require("fs"); | |
| const required = [ | |
| ["quality.yaml", "light-production-validation", "light.zip"], | |
| ["heavy-validation.yaml", "heavy-production-validation", "heavy.zip"], | |
| ]; | |
| for (const [workflow, artifactName, output] of required) { | |
| const response = await github.rest.actions.listWorkflowRuns({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: workflow, | |
| head_sha: context.sha, | |
| status: "completed", | |
| per_page: 100, | |
| }); | |
| const run = response.data.workflow_runs.find( | |
| (item) => item.conclusion === "success" | |
| ); | |
| if (!run) { | |
| core.setFailed(`No successful ${workflow} run found for ${context.sha}`); | |
| return; | |
| } | |
| const artifacts = await github.paginate( | |
| github.rest.actions.listWorkflowRunArtifacts, | |
| { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id: run.id, | |
| per_page: 100, | |
| } | |
| ); | |
| const artifact = artifacts.find( | |
| (item) => item.name === artifactName && !item.expired | |
| ); | |
| if (!artifact) { | |
| core.setFailed(`Missing ${artifactName} on workflow run ${run.id}`); | |
| return; | |
| } | |
| const archive = await github.rest.actions.downloadArtifact({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| artifact_id: artifact.id, | |
| archive_format: "zip", | |
| }); | |
| fs.writeFileSync(output, Buffer.from(archive.data)); | |
| } | |
| - name: Enforce recorded product, restore, security, and benchmark gates | |
| run: | | |
| mkdir -p gate-input/light gate-input/heavy gate-artifacts | |
| unzip -q light.zip -d gate-input/light | |
| unzip -q heavy.zip -d gate-input/heavy | |
| python scripts/assemble_release_artifacts.py --light gate-input/light --heavy gate-input/heavy --output gate-artifacts | |
| python scripts/check_release_readiness.py gate-artifacts | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-evidence-${{ github.ref_name }} | |
| path: gate-artifacts/ | |
| publish: | |
| runs-on: ubuntu-latest | |
| needs: [validate-tag, verify-required-checks] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: release-evidence-${{ github.ref_name }} | |
| path: gate-artifacts | |
| - name: Load and verify the gated image | |
| run: | | |
| gzip -dc gate-artifacts/brainapi-image.tar.gz | docker load | |
| expected=$(python -c 'import json; print(json.load(open("gate-artifacts/security.json"))["image_digest"])') | |
| actual=$(docker image inspect brainapi:ci --format '{{.Id}}') | |
| test "$actual" = "$expected" | |
| - uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - id: publish | |
| name: Publish the unchanged validated image | |
| run: | | |
| target="ghcr.io/lumen-labs/brainapi:$GITHUB_REF_NAME" | |
| docker tag brainapi:ci "$target" | |
| docker push "$target" | |
| digest=$(docker image inspect "$target" --format '{{index .RepoDigests 0}}' | cut -d@ -f2) | |
| test -n "$digest" | |
| echo "$digest" > image-digest.txt | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-image-digest-${{ needs.validate-tag.outputs.version }} | |
| path: image-digest.txt | |