Add support matrix for algorithms in WEB.md #5
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| permissions: | |
| contents: write | |
| id-token: write | |
| attestations: write | |
| packages: write | |
| jobs: | |
| release-artifacts: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: azure/setup-helm@v4 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: derive release image reference | |
| id: image | |
| env: | |
| REGISTRY: ghcr.io | |
| run: | | |
| owner="${GITHUB_REPOSITORY_OWNER,,}" | |
| image_repo="${REGISTRY}/${owner}/pqmsg-server" | |
| echo "repo=${image_repo}" >> "$GITHUB_OUTPUT" | |
| - name: login to ghcr | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: derive image tags | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ steps.image.outputs.repo }} | |
| tags: | | |
| type=ref,event=tag | |
| type=sha,format=long,prefix=sha- | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: block release on unresolved audit findings | |
| run: | | |
| python scripts/security/validate_audit_findings.py | |
| python scripts/security/validate_release_audit_gate.py | |
| - name: render hardened production chart | |
| run: | | |
| helm template pqmsg-server deploy/helm/pqmsg-server \ | |
| --set-string secretEnv.PQMSG_SENTRY_DSN=https://public@example.ingest.sentry.io/project-id >/tmp/pqmsg-server-chart.yaml | |
| - name: verify hardened server boot contract | |
| run: cargo test -p pqmsg-server --bin pqmsg-server | |
| - name: build and publish container image | |
| id: container | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| - name: build release binary | |
| run: cargo build --release -p pqmsg-server | |
| - name: package artifacts | |
| run: | | |
| mkdir -p dist | |
| cp target/release/pqmsg-server dist/pqmsg-server-linux-x86_64 | |
| chmod +x dist/pqmsg-server-linux-x86_64 | |
| - name: render release security posture | |
| run: | | |
| python scripts/security/render_release_security_posture.py --output dist/release-security-posture.json | |
| - name: install cargo-cyclonedx | |
| run: cargo install cargo-cyclonedx --locked | |
| - name: generate SBOM | |
| run: cargo cyclonedx --manifest-path Cargo.toml --format json --all | |
| - name: collect SBOM | |
| run: | | |
| mkdir -p dist/sbom | |
| find . -name 'bom.json' -exec cp --parents {} dist/sbom/ \; | |
| tar -czf dist/sbom.tar.gz -C dist/sbom . | |
| - name: generate release manifest | |
| env: | |
| PQMSG_RELEASE_TAG: ${{ github.ref_name }} | |
| PQMSG_RELEASE_SHA: ${{ github.sha }} | |
| PQMSG_RELEASE_RUN_ID: ${{ github.run_id }} | |
| PQMSG_RELEASE_RUN_ATTEMPT: ${{ github.run_attempt }} | |
| PQMSG_RELEASE_WORKFLOW_REF: ${{ github.workflow_ref }} | |
| PQMSG_RELEASE_IMAGE_REPO: ${{ steps.image.outputs.repo }} | |
| PQMSG_RELEASE_IMAGE_DIGEST: ${{ steps.container.outputs.digest }} | |
| PQMSG_RELEASE_IMAGE_TAGS: ${{ steps.meta.outputs.tags }} | |
| run: | | |
| python - <<'PY' | |
| import hashlib | |
| import json | |
| import os | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| def sha256(path: Path) -> str: | |
| h = hashlib.sha256() | |
| with path.open("rb") as f: | |
| for chunk in iter(lambda: f.read(1024 * 1024), b""): | |
| h.update(chunk) | |
| return h.hexdigest() | |
| binary = Path("dist/pqmsg-server-linux-x86_64") | |
| sbom = Path("dist/sbom.tar.gz") | |
| posture = Path("dist/release-security-posture.json") | |
| manifest = { | |
| "tag": os.environ["PQMSG_RELEASE_TAG"], | |
| "commit_sha": os.environ["PQMSG_RELEASE_SHA"], | |
| "workflow_run_id": os.environ["PQMSG_RELEASE_RUN_ID"], | |
| "workflow_run_attempt": os.environ["PQMSG_RELEASE_RUN_ATTEMPT"], | |
| "workflow_ref": os.environ["PQMSG_RELEASE_WORKFLOW_REF"], | |
| "created_at_utc": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), | |
| "container_images": [ | |
| { | |
| "name": os.environ["PQMSG_RELEASE_IMAGE_REPO"], | |
| "digest": os.environ["PQMSG_RELEASE_IMAGE_DIGEST"], | |
| "immutable_ref": f'{os.environ["PQMSG_RELEASE_IMAGE_REPO"]}@{os.environ["PQMSG_RELEASE_IMAGE_DIGEST"]}', | |
| "tags": [tag.strip() for tag in os.environ["PQMSG_RELEASE_IMAGE_TAGS"].splitlines() if tag.strip()], | |
| "kind": "ghcr-container-image" | |
| } | |
| ], | |
| "artifacts": [ | |
| { | |
| "path": binary.name, | |
| "sha256": sha256(binary), | |
| "size_bytes": binary.stat().st_size, | |
| "kind": "server-binary" | |
| }, | |
| { | |
| "path": sbom.name, | |
| "sha256": sha256(sbom), | |
| "size_bytes": sbom.stat().st_size, | |
| "kind": "sbom-archive" | |
| }, | |
| { | |
| "path": posture.name, | |
| "sha256": sha256(posture), | |
| "size_bytes": posture.stat().st_size, | |
| "kind": "release-security-posture" | |
| } | |
| ] | |
| } | |
| Path("dist/release-manifest.json").write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8") | |
| immutable_ref = manifest["container_images"][0]["immutable_ref"] | |
| Path("dist/container-image.txt").write_text(immutable_ref + "\n", encoding="utf-8") | |
| Path("dist/helm-image-overrides.yaml").write_text( | |
| "\n".join( | |
| [ | |
| "image:", | |
| f" repository: {manifest['container_images'][0]['name']}", | |
| f" digest: {manifest['container_images'][0]['digest']}", | |
| "", | |
| ] | |
| ), | |
| encoding="utf-8", | |
| ) | |
| PY | |
| - name: write checksum manifest | |
| run: | | |
| sha256sum \ | |
| dist/pqmsg-server-linux-x86_64 \ | |
| dist/sbom.tar.gz \ | |
| dist/release-security-posture.json \ | |
| dist/release-manifest.json \ | |
| dist/container-image.txt \ | |
| dist/helm-image-overrides.yaml > dist/checksums.txt | |
| - name: install cosign | |
| uses: sigstore/cosign-installer@v3 | |
| - name: sign checksums | |
| env: | |
| COSIGN_YES: "true" | |
| run: | | |
| cosign sign-blob \ | |
| --output-signature dist/checksums.txt.sig \ | |
| --output-certificate dist/checksums.txt.pem \ | |
| dist/checksums.txt | |
| - name: attest container image provenance | |
| uses: actions/attest-build-provenance@v3 | |
| with: | |
| subject-name: ${{ steps.image.outputs.repo }} | |
| subject-digest: ${{ steps.container.outputs.digest }} | |
| push-to-registry: true | |
| - name: attest server binary provenance | |
| uses: actions/attest@v4 | |
| with: | |
| subject-path: dist/pqmsg-server-linux-x86_64 | |
| - name: attest release manifest provenance | |
| uses: actions/attest@v4 | |
| with: | |
| subject-path: dist/release-manifest.json | |
| - name: attest release security posture provenance | |
| uses: actions/attest@v4 | |
| with: | |
| subject-path: dist/release-security-posture.json | |
| - name: attest SBOM archive provenance | |
| uses: actions/attest@v4 | |
| with: | |
| subject-path: dist/sbom.tar.gz | |
| - name: upload release artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-artifacts-${{ github.ref_name }} | |
| path: dist/* | |
| - name: publish github release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| dist/pqmsg-server-linux-x86_64 | |
| dist/checksums.txt | |
| dist/checksums.txt.sig | |
| dist/checksums.txt.pem | |
| dist/container-image.txt | |
| dist/helm-image-overrides.yaml | |
| dist/release-security-posture.json | |
| dist/release-manifest.json | |
| dist/sbom.tar.gz | |
| generate_release_notes: true |