Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions .github/scripts/public_release_from_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#!/usr/bin/env python3
"""Mirror an already-published Trajectory release without exposing private evidence."""

from __future__ import annotations

import argparse
import os
from pathlib import Path

import public_release_mirror as mirror


SOURCE_REPOSITORY = "DataDog/trajectory"
SOURCE_READ_POLICY = "trajectory-labs.public-release-read"
TARGET_RECEIPT_KIND = "trajectory-public-source-mirror-receipt"
MAX_TOTAL_ASSET_BYTES = 1_100_000_000
REQUIRED_ASSETS = (
"trajectory-darwin-amd64",
"trajectory-darwin-arm64",
"trajectory-darwin-universal",
"trajectory-linux-amd64",
"trajectory-linux-arm64",
"trajectory-windows-amd64.exe",
"trajectory-windows-amd64",
"trajectory-mdm-darwin-amd64",
"trajectory-mdm-darwin-arm64",
"trajectory-mdm-darwin-universal",
"trajectory-mdm-linux-amd64",
"trajectory-mdm-linux-arm64",
"trajectory-mdm-windows-amd64.exe",
"checksums.sha256",
)


def source_contract() -> dict[str, object]:
return {
"source_identity": {
"repository": SOURCE_REPOSITORY,
"read_policy": SOURCE_READ_POLICY,
},
"required_assets": list(REQUIRED_ASSETS),
"limits": {
"max_asset_bytes": 300_000_000,
"max_total_asset_bytes": MAX_TOTAL_ASSET_BYTES,
},
}


def build_request(
source_client: mirror.GitHubClient,
*,
version: str,
target_sha: str,
) -> tuple[dict[str, object], dict[str, object]]:
if not mirror.VERSION_RE.fullmatch(version):
raise mirror.MirrorError("version must be canonical X.Y.Z")
tag = f"v{version}"
release = source_client.get_release_by_tag(tag)
if release is None:
raise mirror.MirrorError("source release does not exist")
if release.get("draft") is not False or release.get("prerelease") is not False:
raise mirror.MirrorError("source release must be published and stable")
latest = source_client.get_latest_release()
if latest.get("id") != release.get("id") or latest.get("tag_name") != tag:
raise mirror.MirrorError("source release must be GitHub latest")

name = mirror.require_string(release.get("name"), "source release name")
body = mirror.require_string(release.get("body"), "source release body", nonempty=False)
published_at = mirror.require_string(
release.get("published_at"), "source release published_at"
)
if not mirror.TIMESTAMP_RE.fullmatch(published_at):
raise mirror.MirrorError("source release published_at must be a UTC timestamp")

by_name = mirror.release_assets_by_name(release)
if set(by_name) != set(REQUIRED_ASSETS):
raise mirror.MirrorError("source release does not contain the canonical asset set")
assets: list[dict[str, object]] = []
total_size = 0
for asset_name in REQUIRED_ASSETS:
asset = by_name[asset_name]
size = mirror.require_positive_int(asset.get("size"), f"source asset {asset_name} size")
digest = mirror.require_string(
asset.get("digest"), f"source asset {asset_name} digest"
)
if not digest.startswith("sha256:") or not mirror.SHA256_RE.fullmatch(digest[7:]):
raise mirror.MirrorError(f"source asset digest is not canonical: {asset_name}")
total_size += size
assets.append({"name": asset_name, "size": size, "sha256": digest[7:]})
if total_size > MAX_TOTAL_ASSET_BYTES:
raise mirror.MirrorError("source release exceeds the bounded mirror size")

request: dict[str, object] = {
"version": version,
"tag": tag,
"release": {
"source_release_id": mirror.require_positive_int(
release.get("id"), "source release id"
),
"name": name,
"body": body,
"target_commitish": target_sha,
},
"asset_manifest": {"assets": assets},
"published_at": published_at,
}
return request, release


def validate_metadata(metadata: dict[str, object], request: dict[str, object]) -> None:
expected = {
"version": request["version"],
"tag": request["tag"],
"released_at": request["published_at"],
}
if metadata.get("stable") != expected or metadata.get("beta") != expected:
raise mirror.MirrorError("RELEASES.json must match the mirrored stable release")


def apply_release(args: argparse.Namespace) -> dict[str, object]:
target_token = os.environ.get("GITHUB_TOKEN")
if not target_token:
raise mirror.MirrorError("GITHUB_TOKEN is required")
contract = source_contract()
source_token = mirror.exchange_source_token(contract)
source_client = mirror.GitHubClient(SOURCE_REPOSITORY, source_token)
target_client = mirror.GitHubClient(args.expected_repository, target_token)
request, source_release = build_request(
source_client,
version=args.version,
target_sha=args.expected_target_sha,
)
validate_metadata(mirror.load_json(args.metadata), request)

with mirror.tempfile.TemporaryDirectory(prefix="trajectory-public-source-mirror-") as directory:
scratch = Path(directory)
source_paths = mirror.materialize_source_assets(
source_client, request, contract, scratch
)
target_release, action = mirror.publish_target_release(
target_client, request, contract, source_paths, scratch
)

receipt = {
"schema_version": 1,
"kind": TARGET_RECEIPT_KIND,
"status": action,
"version": request["version"],
"tag": request["tag"],
"source_release_id": source_release["id"],
"target_release_id": target_release["id"],
"target_sha": args.expected_target_sha,
"workflow_run_id": args.workflow_run_id,
"assets": request["asset_manifest"]["assets"],
"latest": True,
}
args.receipt_out.parent.mkdir(parents=True, exist_ok=True)
args.receipt_out.write_bytes(mirror.canonical_json(receipt) + b"\n")
return receipt


def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--version", required=True)
parser.add_argument("--metadata", required=True, type=Path)
parser.add_argument("--expected-repository", required=True)
parser.add_argument("--expected-target-sha", required=True)
parser.add_argument("--workflow-run-id", required=True, type=int)
parser.add_argument("--receipt-out", required=True, type=Path)
args = parser.parse_args()
try:
apply_release(args)
except mirror.MirrorError as error:
print(f"PUBLIC_SOURCE_MIRROR_ERROR {error}", file=mirror.sys.stderr)
return 2
return 0


if __name__ == "__main__":
raise SystemExit(main())
49 changes: 49 additions & 0 deletions .github/workflows/public-release-breakglass-mirror.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Attested Public Release Mirror
run-name: public-source-mirror-v${{ inputs.version }}

on:
workflow_dispatch:
inputs:
version:
description: Canonical stable release version to mirror from DataDog/trajectory
required: true
type: string

permissions:
contents: read

concurrency:
group: public-source-mirror-v${{ inputs.version }}
cancel-in-progress: false

jobs:
publish:
name: Mirror exact published release
runs-on: ubuntu-latest
environment: public-release-mirror
timeout-minutes: 30
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Validate source and publish exact release
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
python3 .github/scripts/public_release_from_source.py \
--version "${{ inputs.version }}" \
--metadata RELEASES.json \
--expected-repository "$GITHUB_REPOSITORY" \
--expected-target-sha "$GITHUB_SHA" \
--workflow-run-id "$GITHUB_RUN_ID" \
--receipt-out "$RUNNER_TEMP/public-source-mirror-receipt.json"

- name: Retain sanitized publication receipt
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: public-source-mirror-receipt-${{ github.run_id }}
path: ${{ runner.temp }}/public-source-mirror-receipt.json
if-no-files-found: error
retention-days: 90
2 changes: 2 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ jobs:
run: |
python3 -m py_compile \
.github/scripts/public_release_mirror.py \
.github/scripts/public_release_from_source.py \
tests/test_public_release_from_source.py \
tests/test_public_release_mirror.py
python3 .github/scripts/public_release_mirror.py validate-contract \
--contract contracts/public-release-mirror-v1.json
Expand Down
12 changes: 6 additions & 6 deletions RELEASES.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"stable": {
"version": "0.5.36",
"tag": "v0.5.36",
"released_at": "2026-08-17T13:16:32Z"
"version": "0.5.37",
"tag": "v0.5.37",
"released_at": "2026-08-20T23:31:54Z"
},
"beta": {
"version": "0.5.36",
"tag": "v0.5.36",
"released_at": "2026-08-17T13:16:32Z"
"version": "0.5.37",
"tag": "v0.5.37",
"released_at": "2026-08-20T23:31:54Z"
}
}
116 changes: 116 additions & 0 deletions tests/test_public_release_from_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from __future__ import annotations

import importlib.util
import sys
import unittest
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
SCRIPTS = ROOT / ".github" / "scripts"
sys.path.insert(0, str(SCRIPTS))
SCRIPT = SCRIPTS / "public_release_from_source.py"
SPEC = importlib.util.spec_from_file_location("public_release_from_source", SCRIPT)
assert SPEC and SPEC.loader
SOURCE_MIRROR = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(SOURCE_MIRROR)


class FakeSourceClient:
def __init__(self, release: dict[str, object]) -> None:
self.release = release

def get_release_by_tag(self, tag: str) -> dict[str, object] | None:
return self.release if self.release["tag_name"] == tag else None

def get_latest_release(self) -> dict[str, object]:
return self.release


def release_fixture() -> dict[str, object]:
assets = [
{
"id": index + 1,
"name": name,
"size": index + 10,
"digest": f"sha256:{index + 1:064x}",
"state": "uploaded",
}
for index, name in enumerate(SOURCE_MIRROR.REQUIRED_ASSETS)
]
return {
"id": 1234,
"tag_name": "v0.5.37",
"name": "Trajectory 0.5.37",
"body": "Release notes\n",
"published_at": "2026-08-20T23:31:54Z",
"draft": False,
"prerelease": False,
"assets": assets,
}


class PublicReleaseFromSourceTests(unittest.TestCase):
def test_build_request_uses_only_public_release_facts(self) -> None:
release = release_fixture()
request, observed = SOURCE_MIRROR.build_request(
FakeSourceClient(release),
version="0.5.37",
target_sha="a" * 40,
)

self.assertIs(observed, release)
self.assertEqual(request["tag"], "v0.5.37")
self.assertEqual(request["published_at"], "2026-08-20T23:31:54Z")
self.assertEqual(
[asset["name"] for asset in request["asset_manifest"]["assets"]],
list(SOURCE_MIRROR.REQUIRED_ASSETS),
)
self.assertEqual(request["release"]["target_commitish"], "a" * 40)

def test_build_request_rejects_non_latest_release(self) -> None:
release = release_fixture()
client = FakeSourceClient(release)
client.get_latest_release = lambda: {"id": 9999, "tag_name": "v0.5.36"}

with self.assertRaisesRegex(SOURCE_MIRROR.mirror.MirrorError, "GitHub latest"):
SOURCE_MIRROR.build_request(
client,
version="0.5.37",
target_sha="a" * 40,
)

def test_build_request_rejects_asset_set_drift(self) -> None:
release = release_fixture()
release["assets"] = release["assets"][:-1]

with self.assertRaisesRegex(SOURCE_MIRROR.mirror.MirrorError, "canonical asset set"):
SOURCE_MIRROR.build_request(
FakeSourceClient(release),
version="0.5.37",
target_sha="a" * 40,
)

def test_metadata_must_advance_stable_and_beta_together(self) -> None:
request = {
"version": "0.5.37",
"tag": "v0.5.37",
"published_at": "2026-08-20T23:31:54Z",
}
expected = {
"version": "0.5.37",
"tag": "v0.5.37",
"released_at": "2026-08-20T23:31:54Z",
}
SOURCE_MIRROR.validate_metadata(
{"stable": expected, "beta": expected.copy()}, request
)
with self.assertRaisesRegex(SOURCE_MIRROR.mirror.MirrorError, "RELEASES.json"):
SOURCE_MIRROR.validate_metadata(
{"stable": expected, "beta": {**expected, "version": "0.5.36"}},
request,
)


if __name__ == "__main__":
unittest.main()