A fork of attic a self-hostable Nix Binary Cache server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Build and push multi-arch images

Fixes #147.

+141 -21
+60
.ci/build-and-push-images.sh
··· 1 + #!/usr/bin/env bash 2 + set -euo pipefail 3 + 4 + if [[ "$#" -lt "2" ]]; then 5 + >&2 echo "Usage: $0 <image name> <tag1> ..." 6 + >&2 echo "Example: $0 ghcr.io/zhaofengli/attic main abcd123" 7 + exit 1 8 + fi 9 + 10 + cleanup() { 11 + if [[ -f "${manifest_spec}" ]]; then 12 + rm "${manifest_spec}" 13 + fi 14 + } 15 + trap cleanup EXIT 16 + 17 + image_name="$1" 18 + tags=("${@:2}") 19 + 20 + manifest_spec="$(mktemp -t attic-manifest-spec.XXXXXXXXXX)" 21 + 22 + declare -a digests 23 + 24 + emit_header() { 25 + echo "image: ${image_name}" 26 + echo "tags:" 27 + for tag in "${tags[@]}"; do 28 + echo "- ${tag}" 29 + done 30 + echo "manifests:" 31 + } 32 + 33 + push_digest() { 34 + source_image="docker-archive:$1" 35 + digest="$(skopeo inspect "${source_image}" | jq -r .Digest)" 36 + target_image="docker://${image_name}@${digest}" 37 + 38 + >&2 echo "${source_image} ▸ ${target_image}" 39 + >&2 skopeo copy --insecure-policy "${source_image}" "${target_image}" 40 + 41 + echo -n "- " 42 + skopeo inspect "${source_image}" | \ 43 + jq '{platform: {architecture: .Architecture, os: .Os}, image: ($image_name + "@" + .Digest)}' \ 44 + --arg image_name "${image_name}" 45 + } 46 + 47 + >>"${manifest_spec}" emit_header 48 + 49 + nix build .#attic-server-image .#attic-server-image-aarch64 -L --print-out-paths | \ 50 + while read -r output; do 51 + >>"${manifest_spec}" push_digest "${output}" 52 + done 53 + 54 + >&2 echo "----------" 55 + >&2 echo "Generated manifest-tool spec:" 56 + >&2 echo "----------" 57 + cat "${manifest_spec}" 58 + >&2 echo "----------" 59 + 60 + manifest-tool push from-spec "${manifest_spec}"
+77 -21
.github/workflows/build.yml
··· 4 4 push: 5 5 env: 6 6 REGISTRY: ghcr.io 7 - IMAGE_NAME: ${{ github.repository }} 7 + IMAGE_NAME: ghcr.io/${{ github.repository }} 8 8 jobs: 9 9 tests: 10 10 strategy: ··· 17 17 - "2.24" 18 18 - "default" 19 19 runs-on: ${{ matrix.os }} 20 - permissions: 21 - contents: read 22 - packages: write 23 20 steps: 24 21 - uses: actions/checkout@v4.1.1 25 22 ··· 38 35 fi 39 36 40 37 - name: Configure Attic 38 + continue-on-error: true 41 39 run: | 42 40 : "${ATTIC_SERVER:=https://staging.attic.rs/}" 43 41 : "${ATTIC_CACHE:=attic-ci}" ··· 75 73 .#internalMatrix."$system".\"${{ matrix.nix }}\".cargoArtifacts \ 76 74 | xargs attic push "ci:$ATTIC_CACHE" 77 75 fi 76 + 77 + image: 78 + runs-on: ubuntu-latest 79 + if: github.event_name == 'push' 80 + needs: 81 + - tests 82 + permissions: 83 + contents: read 84 + packages: write 85 + steps: 86 + - uses: actions/checkout@v4.1.1 87 + 88 + - name: Install current Bash on macOS 89 + if: runner.os == 'macOS' 90 + run: | 91 + command -v brew && brew install bash || true 92 + 93 + - uses: DeterminateSystems/nix-installer-action@v9 94 + continue-on-error: true # Self-hosted runners already have Nix installed 95 + 96 + - name: Install Attic 97 + run: | 98 + if ! command -v attic &> /dev/null; then 99 + ./.github/install-attic-ci.sh 100 + fi 101 + 102 + - name: Configure Attic 103 + continue-on-error: true 104 + run: | 105 + : "${ATTIC_SERVER:=https://staging.attic.rs/}" 106 + : "${ATTIC_CACHE:=attic-ci}" 107 + echo ATTIC_CACHE=$ATTIC_CACHE >>$GITHUB_ENV 108 + export PATH=$HOME/.nix-profile/bin:$PATH # FIXME 109 + attic login --set-default ci "$ATTIC_SERVER" "$ATTIC_TOKEN" 110 + attic use "$ATTIC_CACHE" 111 + env: 112 + ATTIC_SERVER: ${{ secrets.ATTIC_SERVER }} 113 + ATTIC_CACHE: ${{ secrets.ATTIC_CACHE }} 114 + ATTIC_TOKEN: ${{ secrets.ATTIC_TOKEN }} 115 + 116 + - name: Cache dev shell 117 + run: | 118 + .ci/cache-shell.sh 119 + system=$(nix-instantiate --eval -E 'builtins.currentSystem') 120 + echo system=$system >>$GITHUB_ENV 121 + 78 122 - name: Log in to the Container registry 79 123 uses: docker/login-action@v3.0.0 80 - if: runner.os == 'Linux' && github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) 81 124 with: 82 125 registry: ${{ env.REGISTRY }} 83 126 username: ${{ github.actor }} 84 127 password: ${{ secrets.GITHUB_TOKEN }} 85 128 86 - - name: Push build container image 87 - if: runner.os == 'Linux' && github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) 129 + - name: Build and push container images 88 130 continue-on-error: true 89 131 run: | 90 - IMAGE_ID=ghcr.io/${IMAGE_NAME} 91 - TARBALL=$(nix build --json .#attic-server-image | jq -r '.[].outputs.out') 92 - BRANCH=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') 93 - TAG="${{ github.sha }}" 94 - [[ "${{ github.ref }}" == "refs/tags/"* ]] && TAG=$(echo $BRANCH | sed -e 's/^v//') 95 - docker load < ${TARBALL} 96 - echo IMAGE_ID=$IMAGE_ID 97 - echo TAG=$TAG 98 - docker tag attic-server:main "${IMAGE_ID}:${TAG}" 99 - docker push ${IMAGE_ID}:${TAG} 100 - if [ "$BRANCH" == "main" ]; then 101 - TAG="latest" 102 - docker tag attic-server:main "${IMAGE_ID}:${TAG}" 103 - docker push ${IMAGE_ID}:${TAG} 132 + declare -a tags 133 + tags+=("${{ github.sha }}") 134 + 135 + branch=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') 136 + if [[ "${{ github.ref }}" == "refs/tags/"* ]]; then 137 + tags+=("$(echo $branch | sed -e 's/^v//')") 138 + else 139 + tags+=("${branch}") 140 + fi 141 + 142 + if [ "$branch" == "${{ github.event.repository.default_branch }}" ]; then 143 + tags+=("latest") 144 + fi 145 + 146 + >&2 echo "Image: ${IMAGE_NAME}" 147 + >&2 echo "Tags: ${tags[@]}" 148 + 149 + .ci/run just ci-build-and-push-images "${IMAGE_NAME}" "${tags[@]}" 150 + 151 + # TODO: Just take a diff of the list of store paths, also abstract all of this out 152 + - name: Push build artifacts 153 + run: | 154 + export PATH=$HOME/.nix-profile/bin:$PATH # FIXME 155 + if [ -n "$ATTIC_TOKEN" ]; then 156 + nix build --no-link --print-out-paths -L \ 157 + .#attic-server-image \ 158 + .#attic-server-image-aarch64 \ 159 + | xargs attic push "ci:$ATTIC_CACHE" 104 160 fi
+4
justfile
··· 45 45 # (CI) Run rustfmt check 46 46 ci-rustfmt: 47 47 cargo fmt --check 48 + 49 + # (CI) Build and push images 50 + ci-build-and-push-images *args: 51 + .ci/build-and-push-images.sh {{ args }}