|
| 1 | +#!/bin/bash |
| 2 | +set -e |
| 3 | + |
| 4 | +# --- CONFIGURATION --- |
| 5 | +# Detect the repository name (user/repo) |
| 6 | +FULL_REPO="${GITHUB_REPOSITORY:-local/test-repo}" |
| 7 | +REPO_URL="https://github.com/${FULL_REPO}" |
| 8 | +IMAGE="ghcr.io/$FULL_REPO" |
| 9 | +TAG="${GITHUB_REF_NAME:-v1}" |
| 10 | +SRC_DIR="./files" |
| 11 | +# --------------------- |
| 12 | + |
| 13 | +log_info() { echo -e "\033[1;34m[INFO]\033[0m $1"; } |
| 14 | +log_step() { echo -e "\033[1;33m[STEP $1]\033[0m $2"; } |
| 15 | +log_success() { echo -e "\033[1;32m[SUCCESS]\033[0m $1"; } |
| 16 | + |
| 17 | +log_info "Initializing OCI artifact publication sequence." |
| 18 | + |
| 19 | +# 0. Metadata Discovery |
| 20 | +log_step "0/5" "Gathering metadata from environment..." |
| 21 | + |
| 22 | +# 1. Prepare the data layer |
| 23 | +log_step "1/5" "Packaging filesystem layer from: $SRC_DIR" |
| 24 | +tar -czf layer.tar.gz -C "$SRC_DIR" . |
| 25 | + |
| 26 | +# Calculate the DiffID |
| 27 | +log_step "2/5" "Calculating data integrity checksums (DiffID)..." |
| 28 | +DIFF_ID=$(gzip -d -c layer.tar.gz | (sha256sum 2>/dev/null || shasum -a 256) | awk '{print $1}') |
| 29 | + |
| 30 | +# Upload the layer |
| 31 | +log_step "3/5" "Uploading raw data blob..." |
| 32 | +LAYER_DESC=$(oras blob push "$IMAGE" layer.tar.gz --descriptor) |
| 33 | + |
| 34 | +# --- BUILD FUNCTION --- |
| 35 | +build_arch() { |
| 36 | + local ARCH=$1 |
| 37 | + echo " [INFO] Processing architecture: $ARCH" >&2 |
| 38 | + |
| 39 | + # A. Config Blob |
| 40 | + jq --arg arch "$ARCH" --arg diff "sha256:$DIFF_ID" \ |
| 41 | + '.architecture = $arch | .rootfs.diff_ids[0] = $diff' \ |
| 42 | + templates/config.json > "config-$ARCH.json" |
| 43 | + |
| 44 | + local CFG_DESC=$(oras blob push "$IMAGE" "config-$ARCH.json" --descriptor) |
| 45 | + |
| 46 | + # B. Manifest |
| 47 | + jq --argjson cfg "$CFG_DESC" \ |
| 48 | + --argjson layer "$LAYER_DESC" \ |
| 49 | + --arg src "$REPO_URL" \ |
| 50 | + '.config.digest = $cfg.digest | .config.size = $cfg.size | |
| 51 | + .layers[0].digest = $layer.digest | .layers[0].size = $layer.size | |
| 52 | + .annotations["org.opencontainers.image.source"] = $src' \ |
| 53 | + templates/manifest.json > "manifest-$ARCH.json" |
| 54 | + |
| 55 | + oras manifest push "$IMAGE" "manifest-$ARCH.json" --descriptor |
| 56 | +} |
| 57 | + |
| 58 | +# --- EXECUTION --- |
| 59 | + |
| 60 | +log_step "4/5" "Building manifests..." |
| 61 | +AMD_DESC=$(build_arch "amd64") |
| 62 | +ARM_DESC=$(build_arch "arm64") |
| 63 | + |
| 64 | +# Create Index |
| 65 | +log_step "5/5" "Constructing OCI Image Index..." |
| 66 | +jq --argjson amd "$AMD_DESC" \ |
| 67 | + --argjson arm "$ARM_DESC" \ |
| 68 | + --arg src "$REPO_URL" \ |
| 69 | + '.manifests[0].digest = $amd.digest | .manifests[0].size = $amd.size | |
| 70 | + .manifests[1].digest = $arm.digest | .manifests[1].size = $arm.size | |
| 71 | + .annotations["org.opencontainers.image.source"] = $src' \ |
| 72 | + templates/index.json > index_final.json |
| 73 | + |
| 74 | +log_info "Publishing final tag: $IMAGE:$TAG" |
| 75 | +oras manifest push "$IMAGE:$TAG" index_final.json > /dev/null |
| 76 | + |
| 77 | +# Cleanup |
| 78 | +rm layer.tar.gz config-*.json manifest-*.json index_final.json |
| 79 | + |
| 80 | +echo "" |
| 81 | +log_success "Artifact published successfully." |
0 commit comments