Skip to content

Add support matrix for algorithms in WEB.md #5

Add support matrix for algorithms in WEB.md

Add support matrix for algorithms in WEB.md #5

Workflow file for this run

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