mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Bind container qualification to caller commit
Change-source: pulse-maintainer
This commit is contained in:
@@ -862,4 +862,3 @@ jobs:
|
||||
with:
|
||||
version: ${{ inputs.version }}
|
||||
container_artifact: ${{ needs.build.outputs.container_artifact_name }}
|
||||
source_sha: ${{ github.sha }}
|
||||
|
||||
@@ -257,7 +257,6 @@ jobs:
|
||||
with:
|
||||
version: ${{ needs.prepare.outputs.version }}
|
||||
container_artifact: ${{ needs.build_release_candidate.outputs.container_artifact_name }}
|
||||
source_sha: ${{ github.sha }}
|
||||
|
||||
# Build the embed bundle independently so backend and smoke lanes can start
|
||||
# without waiting for the full frontend quality suite.
|
||||
|
||||
@@ -11,10 +11,6 @@ on:
|
||||
description: 'Exact-candidate container payload artifact from this run'
|
||||
required: true
|
||||
type: string
|
||||
source_sha:
|
||||
description: 'Exact source commit bound to the candidate payload'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -31,7 +27,16 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ inputs.source_sha }}
|
||||
# A reusable workflow inherits github.sha from its caller. Do not
|
||||
# accept a caller-controlled checkout ref: the caller event commit is
|
||||
# the immutable source identity for both code and candidate payload.
|
||||
ref: ${{ github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Verify exact caller source
|
||||
env:
|
||||
EXPECTED_SOURCE_SHA: ${{ github.sha }}
|
||||
run: test "$(git rev-parse HEAD)" = "${EXPECTED_SOURCE_SHA}"
|
||||
|
||||
- name: Download exact-candidate container payload
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
@@ -45,7 +50,7 @@ jobs:
|
||||
--release-dir "$RUNNER_TEMP/release-container-payload/payload" \
|
||||
--manifest "$RUNNER_TEMP/release-container-payload/release-container-payload.json" \
|
||||
--version "${{ inputs.version }}" \
|
||||
--source-sha "${{ inputs.source_sha }}"
|
||||
--source-sha "${{ github.sha }}"
|
||||
|
||||
- name: Assemble exact-candidate runtime and agent images
|
||||
run: |
|
||||
|
||||
@@ -1513,6 +1513,56 @@ func TestReleaseWorkflowsUseSecretSafeAttestedImageBuilds(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseContainerQualificationBindsCheckoutToCallerCommit(t *testing.T) {
|
||||
qualifierBytes, err := os.ReadFile(repoFile(".github", "workflows", "qualify-release-containers.yml"))
|
||||
if err != nil {
|
||||
t.Fatalf("read qualify-release-containers.yml: %v", err)
|
||||
}
|
||||
candidateBytes, err := os.ReadFile(repoFile(".github", "workflows", "build-release-candidate.yml"))
|
||||
if err != nil {
|
||||
t.Fatalf("read build-release-candidate.yml: %v", err)
|
||||
}
|
||||
releaseBytes, err := os.ReadFile(repoFile(".github", "workflows", "create-release.yml"))
|
||||
if err != nil {
|
||||
t.Fatalf("read create-release.yml: %v", err)
|
||||
}
|
||||
|
||||
qualifier := string(qualifierBytes)
|
||||
qualifyJob := workflowJobBlock(t, qualifier, "qualify")
|
||||
for _, required := range []string{
|
||||
`ref: ${{ github.sha }}`,
|
||||
`persist-credentials: false`,
|
||||
`EXPECTED_SOURCE_SHA: ${{ github.sha }}`,
|
||||
`test "$(git rev-parse HEAD)" = "${EXPECTED_SOURCE_SHA}"`,
|
||||
`--source-sha "${{ github.sha }}"`,
|
||||
} {
|
||||
if !strings.Contains(qualifyJob, required) {
|
||||
t.Fatalf("release container qualification does not fail closed on the exact caller commit: %s", required)
|
||||
}
|
||||
}
|
||||
for _, forbidden := range []string{
|
||||
"inputs.source_sha",
|
||||
"source_sha:",
|
||||
} {
|
||||
if strings.Contains(qualifier, forbidden) {
|
||||
t.Fatalf("release container qualification must not accept an arbitrary source ref: %s", forbidden)
|
||||
}
|
||||
}
|
||||
|
||||
callerJobs := map[string]string{
|
||||
"build-release-candidate.yml": workflowJobBlock(t, string(candidateBytes), "qualify-release-containers"),
|
||||
"create-release.yml": workflowJobBlock(t, string(releaseBytes), "qualify_release_containers"),
|
||||
}
|
||||
for caller, job := range callerJobs {
|
||||
if strings.Contains(job, "source_sha:") {
|
||||
t.Fatalf("%s must not forward a caller-selectable source ref to container qualification", caller)
|
||||
}
|
||||
if !strings.Contains(job, "uses: ./.github/workflows/qualify-release-containers.yml") {
|
||||
t.Fatalf("%s no longer calls the trusted container qualifier", caller)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeploymentDefaultsPinVersionedImagesAndHelmDocsChecksum(t *testing.T) {
|
||||
versionBytes, err := os.ReadFile(repoFile("VERSION"))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user