mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
ad1cfd33c3
The grouped action upgrade leaves signing, network and publication consumer assertions on superseded pins. Align those contracts and check every consumer against reviewed immutable upstream manifests, retaining exact dispatch and release trust boundaries without claiming hosted execution. Change-source: pulse-maintainer
182 lines
7.0 KiB
YAML
182 lines
7.0 KiB
YAML
name: Compile Release Payload on Hosted Runner
|
|
run-name: Compile v${{ inputs.version }} payload for request ${{ inputs.request_id }}
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: 'Version number without the leading v'
|
|
required: true
|
|
type: string
|
|
source_sha:
|
|
description: 'Exact public Pulse source commit to compile'
|
|
required: true
|
|
type: string
|
|
request_id:
|
|
description: 'Parent release workflow run and attempt identifier'
|
|
required: true
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
compile-release-payload:
|
|
name: Compile Exact-SHA Release Payload on Ephemeral VM
|
|
# Release binaries are a production trust boundary. Keep this job on a
|
|
# fresh GitHub-hosted VM rather than a persistent public-repository runner,
|
|
# whose state can survive earlier jobs and influence later compilation.
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 30
|
|
steps:
|
|
- name: Validate isolated compiler request
|
|
env:
|
|
EXPECTED_SOURCE_SHA: ${{ inputs.source_sha }}
|
|
REQUEST_ID: ${{ inputs.request_id }}
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
set -euo pipefail
|
|
[[ "${EXPECTED_SOURCE_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
[[ "${REQUEST_ID}" =~ ^[0-9]+-[0-9]+$ ]]
|
|
[[ "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-((rc|alpha|beta)\.[0-9]+))?$ ]]
|
|
test "${GITHUB_SHA}" = "${EXPECTED_SOURCE_SHA}"
|
|
test "${GITHUB_WORKFLOW_SHA}" = "${EXPECTED_SOURCE_SHA}"
|
|
|
|
- name: Checkout exact release source
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
ref: ${{ inputs.source_sha }}
|
|
|
|
- name: Validate candidate identity
|
|
env:
|
|
EXPECTED_SOURCE_SHA: ${{ inputs.source_sha }}
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
set -euo pipefail
|
|
test "$(tr -d '\n' < VERSION)" = "${VERSION}"
|
|
test "$(git rev-parse HEAD)" = "${EXPECTED_SOURCE_SHA}"
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: false
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '24'
|
|
package-manager-cache: false
|
|
|
|
- name: Verify compiler capacity
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
available_memory_kib="$(awk '$1 == "MemAvailable:" {print $2}' /proc/meminfo)"
|
|
minimum_memory_kib="$((6 * 1024 * 1024))"
|
|
available_disk_bytes="$(df --output=avail -B1 "$RUNNER_TEMP" | tail -n 1 | tr -d ' ')"
|
|
minimum_disk_bytes="$((10 * 1024 * 1024 * 1024))"
|
|
if (( available_memory_kib < minimum_memory_kib )); then
|
|
echo "::error::Release compiler has less than 6 GiB available memory."
|
|
exit 1
|
|
fi
|
|
if (( available_disk_bytes < minimum_disk_bytes )); then
|
|
echo "::error::Release compiler has less than 10 GiB free under RUNNER_TEMP."
|
|
exit 1
|
|
fi
|
|
echo "Release compiler capacity: $((available_memory_kib / 1024)) MiB memory, $((available_disk_bytes / 1024 / 1024 / 1024)) GiB disk."
|
|
|
|
- name: Compile credential-free release payload
|
|
env:
|
|
PULSE_LICENSE_PUBLIC_KEY: ${{ secrets.PULSE_LICENSE_PUBLIC_KEY }}
|
|
PULSE_UPDATE_SIGNING_PUBLIC_KEY: ${{ vars.PULSE_UPDATE_SIGNING_PUBLIC_KEY }}
|
|
PULSE_RELEASE_BUILD_JOBS: "2"
|
|
VERSION: ${{ inputs.version }}
|
|
run: ./scripts/build-release-binaries.sh "${VERSION}" "$RUNNER_TEMP/release-compiled"
|
|
|
|
- name: Upload exact-SHA compiled payload
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: release-compiled-${{ inputs.source_sha }}-${{ inputs.version }}-${{ inputs.request_id }}
|
|
path: ${{ runner.temp }}/release-compiled/
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
compression-level: 0
|
|
overwrite: true
|
|
|
|
compile-secure-runtime-qualification:
|
|
name: Compile Hosted Secure Runtime Qualification Packet
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 20
|
|
permissions:
|
|
attestations: write
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- name: Validate isolated compiler request
|
|
env:
|
|
EXPECTED_SOURCE_SHA: ${{ inputs.source_sha }}
|
|
REQUEST_ID: ${{ inputs.request_id }}
|
|
run: |
|
|
set -euo pipefail
|
|
[[ "${EXPECTED_SOURCE_SHA}" =~ ^[0-9a-f]{40}$ ]]
|
|
[[ "${REQUEST_ID}" =~ ^[0-9]+-[0-9]+$ ]]
|
|
test "${GITHUB_SHA}" = "${EXPECTED_SOURCE_SHA}"
|
|
test "${GITHUB_WORKFLOW_SHA}" = "${EXPECTED_SOURCE_SHA}"
|
|
|
|
- name: Checkout exact release source
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
ref: ${{ inputs.source_sha }}
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: false
|
|
|
|
- name: Build hosted qualification subjects
|
|
env:
|
|
EXPECTED_SOURCE_SHA: ${{ inputs.source_sha }}
|
|
PULSE_UPDATE_SIGNING_PUBLIC_KEY: ${{ vars.PULSE_UPDATE_SIGNING_PUBLIC_KEY }}
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
set -euo pipefail
|
|
test "$(tr -d '\n' < VERSION)" = "${VERSION}"
|
|
test "$(git rev-parse HEAD)" = "${EXPECTED_SOURCE_SHA}"
|
|
./scripts/build-secure-runtime-qualification.sh \
|
|
"${VERSION}" \
|
|
"$RUNNER_TEMP/secure-runtime-qualification" \
|
|
amd64
|
|
|
|
- name: Attest hosted qualification subjects
|
|
id: attest_secure_runtime
|
|
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
|
|
with:
|
|
subject-checksums: ${{ runner.temp }}/secure-runtime-qualification/secure-runtime-compiler-subjects.sha256
|
|
|
|
- name: Preserve portable compiler provenance
|
|
env:
|
|
PROVENANCE_BUNDLE: ${{ steps.attest_secure_runtime.outputs.bundle-path }}
|
|
run: |
|
|
set -euo pipefail
|
|
test -s "${PROVENANCE_BUNDLE}"
|
|
jq -e 'type == "object"' "${PROVENANCE_BUNDLE}" >/dev/null
|
|
install -m 0644 \
|
|
"${PROVENANCE_BUNDLE}" \
|
|
"$RUNNER_TEMP/secure-runtime-qualification/secure-runtime-compiler-provenance.sigstore.json"
|
|
|
|
- name: Upload hosted qualification packet
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: secure-runtime-qualification-${{ inputs.source_sha }}-${{ inputs.version }}-${{ inputs.request_id }}
|
|
path: ${{ runner.temp }}/secure-runtime-qualification/
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
compression-level: 0
|
|
overwrite: true
|