name: Release integrity
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Check out source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with:
fetch-depth: 0
- name: Validate repository policy
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
import subprocess
reference = re.compile(r"^\s*(?:-\s*)?uses:\s*[^@\s]+@([0-9a-f]{40})(?:\s+#.*)?$")
for workflow in Path(".github/workflows").glob("*.yml"):
for number, line in enumerate(workflow.read_text(encoding="utf-8").splitlines(), 1):
if re.match(r"^\s*(?:-\s*)?uses:", line) and not reference.fullmatch(line):
raise SystemExit(f"{workflow}:{number}: action reference is not immutable")
paths = subprocess.check_output(["git", "ls-files"], text=True).splitlines()
for path in paths:
parts = Path(path).parts
if "hooks" in parts:
raise SystemExit(f"tracked hook path is forbidden: {path}")
if path.startswith(".") and not path.startswith((".cargo/", ".github/", ".gitignore")):
raise SystemExit(f"unapproved hidden metadata path: {path}")
message = subprocess.check_output(["git", "log", "-1", "--format=%B"], text=True)
trailers = subprocess.run(
["git", "interpret-trailers", "--parse"],
input=message,
text=True,
check=True,
capture_output=True,
).stdout.strip()
if trailers:
raise SystemExit("commit message trailers are forbidden")
forbidden_write = "contents:" + " write"
forbidden_push = "git" + " push"
for workflow in Path(".github/workflows").glob("*.yml"):
text = workflow.read_text(encoding="utf-8")
if forbidden_write in text or forbidden_push in text:
raise SystemExit(f"{workflow}: source workflows must not write repository contents")
PY
- name: Verify pushed commit identity
if: ${{ github.event_name == 'push' }}
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
import json
import os
import urllib.request
url = f"{os.environ['GITHUB_API_URL']}/repos/{os.environ['GITHUB_REPOSITORY']}/commits/{os.environ['GITHUB_SHA']}"
request = urllib.request.Request(
url,
headers={
"Authorization": f"Bearer {os.environ['GH_TOKEN']}",
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
},
)
with urllib.request.urlopen(request) as response:
commit = json.load(response)
if commit["sha"] != os.environ["GITHUB_SHA"]:
raise SystemExit("remote commit identity mismatch")
if not commit["commit"]["verification"]["verified"]:
raise SystemExit("remote commit signature is not verified")
PY