Skip to content

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”— Linked Artifacts Demo

A comprehensive demo of GitHub's Linked Artifacts feature β€” showing how to track what's deployed in each environment and enforce promotion ordering.

What is Linked Artifacts?

Linked Artifacts is a GitHub Enterprise Cloud feature that provides an org-wide view of software artifacts built with GitHub Actions. It tracks:

  • Storage records β€” what was built, where it's stored, and its provenance attestation
  • Deployment records β€” which environments an artifact is deployed to and its runtime risks

Find it at: Organization β†’ Packages tab β†’ Linked artifacts (left sidebar)

Linked Artifacts vs. Deployments Dashboard

Deployments Dashboard Linked Artifacts
Scope Per-repo Org-wide
Tracks Commits/refs Artifacts (with cryptographic digest)
Security No integration Feeds into code scanning & Dependabot alert prioritization
Provenance None Signed SLSA attestations
Runtime risks No Yes (internet-exposed, sensitive data)

What This Demo Does

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          β”‚    β”‚          β”‚    β”‚          β”‚    β”‚          β”‚    β”‚          β”‚
β”‚  Build   │───▢│   Dev    │───▢│   QA     │───▢│ Staging  │───▢│   Prod   β”‚
β”‚          β”‚    β”‚          β”‚    β”‚          β”‚    β”‚          β”‚    β”‚          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚               β”‚               β”‚               β”‚               β”‚
     β”‚               β”‚               β”‚               β”‚               β”‚
     β–Ό               β–Ό               β–Ό               β–Ό               β–Ό
  Push to         Register        Verify Dev      Verify QA      Verify Staging
  GHCR +          deployment      deployment      deployment     deployment
  Attest          record          record exists   record exists  record exists
  (auto-creates   (Dev)           β†’ Register QA   β†’ Register     β†’ Register
  storage                                         Staging        Production
  record)

Three Workflows

1. build-and-deploy.yml β€” Docker Container (Happy Path)

Triggered on push to main. Builds a Docker image, pushes to GHCR, attests provenance, then deploys sequentially through all 4 environments. Each promotion step:

  • Verifies the artifact was deployed to the prior environment (via Linked Artifacts API)
  • Registers a deployment record after successful deployment

2. build-and-deploy-dotnet.yml β€” .NET File Artifact (Happy Path) πŸ“„

Same promotion flow, but with a ZIP file instead of a container. This demonstrates that linked artifacts works with any hashable build output. Key differences:

  • Digest is computed by hashing the ZIP file (sha256sum)
  • Attestation uses subject-path instead of subject-name/subject-digest
  • Storage record is registered manually via REST API (no auto-creation for files)
  • Artifact is stored as a GitHub Actions artifact, not in a registry

3. hotfix-skip-env.yml β€” Negative Test ❌

Manually triggered. Builds a new image and tries to deploy it directly to a higher environment (e.g., Staging), skipping the lower ones. The verification gate blocks this because no prior deployment records exist for the new image's digest.

This proves the enforcement isn't just needs: job ordering β€” it's the real API check.

How It Works

1. Build & Attest

Container (Docker): The build job pushes a Docker image to GHCR and generates a signed provenance attestation using actions/attest. With push-to-registry: true and artifact-metadata: write permission, this automatically creates a storage record on the linked artifacts page.

.NET (File): The build job publishes the app, zips it, computes a sha256 hash, attests using subject-path, and manually registers a storage record via REST API. This shows linked artifacts works without a container registry.

Container (Docker) File (.NET ZIP)
Digest source Registry provides it automatically Hash the file with sha256sum
Attestation subject-name + subject-digest + push-to-registry: true subject-path
Storage record Auto-created by actions/attest Manual POST to REST API
Artifact storage GHCR GitHub Actions artifact

2. Deployment Records

After each deployment, the workflow calls the artifact metadata REST API:

gh api -X POST \
  "orgs/{org}/artifacts/metadata/deployment-record" \
  -f name="linked-artifacts-demo" \
  -f digest="sha256:abc..." \
  -f status="deployed" \
  -f logical_environment="production" \
  -f deployment_name="prod-deploy-42" \
  -f github_repository="org/repo"

3. Verification Gate

Before each promotion, the verify-deployment.sh script queries the API:

GET /orgs/{org}/artifacts/{digest}/metadata/deployment-records

It checks if a deployment record exists for the required prior environment. If not, the job fails and promotion is blocked.

Environment Mapping

GitHub Environment logical_environment Requires Prior
Dev development β€” (first)
QA testing development
Staging staging testing
Production production staging

Setup

Prerequisites

  • GitHub Enterprise Cloud organization
  • Repository in the organization with Actions enabled
  • artifact-metadata: write permission available (GHEC feature)

1. Create GitHub Environments

Create the 4 environments for the repository. You can do this in Settings β†’ Environments or via the API:

# Create all 4 environments
for env in Dev QA Staging Production; do
  gh api -X PUT \
    "repos/{owner}/{repo}/environments/${env}" \
    --silent
done

# Optionally add a wait timer to Production
gh api -X PUT \
  "repos/{owner}/{repo}/environments/Production" \
  -f "wait_timer=1" \
  --silent

2. Push Code & Trigger

git add -A
git commit -m "Add linked artifacts demo"
git push origin main

The build-and-deploy.yml workflow will trigger automatically.

3. View Results

After the pipeline completes:

  1. Go to your Organization page
  2. Click the Packages tab
  3. Click Linked artifacts in the left sidebar
  4. Find linked-artifacts-demo β€” you'll see:
    • Storage record with provenance attestation
    • Deployment records for Dev, QA, Staging, and Production

4. Test the Negative Case

  1. Go to Actions β†’ "Hotfix: Skip Environment (Demo)"
  2. Click Run workflow
  3. Select Staging or Production as the target
  4. Watch the verification gate fail because the new image was never deployed to the lower environments

Repository Structure

β”œβ”€β”€ .github/
β”‚   β”œβ”€β”€ scripts/
β”‚   β”‚   └── verify-deployment.sh       # Reusable verification gate
β”‚   └── workflows/
β”‚       β”œβ”€β”€ build-and-deploy.yml       # Docker container pipeline
β”‚       β”œβ”€β”€ build-and-deploy-dotnet.yml # .NET file artifact pipeline
β”‚       └── hotfix-skip-env.yml        # Negative test (skip environments)
β”œβ”€β”€ src/
β”‚   └── index.js                       # Simple Express.js app (Docker demo)
β”œβ”€β”€ dotnet-app/                        # .NET Web API app (file artifact demo)
β”‚   β”œβ”€β”€ Program.cs
β”‚   β”œβ”€β”€ dotnet-app.csproj
β”‚   └── ...
β”œβ”€β”€ Dockerfile                         # Docker build for Node.js app
β”œβ”€β”€ package.json
└── README.md

Key API Endpoints

Endpoint Method Purpose
orgs/{org}/artifacts/metadata/storage-record POST Register where an artifact is stored
orgs/{org}/artifacts/metadata/deployment-record POST Register a deployment to an environment
orgs/{org}/artifacts/{digest}/metadata/deployment-records GET List deployment records for an artifact
orgs/{org}/artifacts/{digest}/metadata/storage-records GET List storage records for an artifact

Links

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages