Skip to content

Merge pull request #5329 from brunomiguel/q #546

Merge pull request #5329 from brunomiguel/q

Merge pull request #5329 from brunomiguel/q #546

Workflow file for this run

name: Build Wolfi OS
on:
push:
branches: ['main']
paths-ignore:
- '**.md'
- '**.txt'
workflow_dispatch:
# Only run one build at a time to prevent out of sync signatures
concurrency:
group: build-${{ github.ref }}
jobs:
build:
name: Build packages
if: github.repository == 'wolfi-dev/os'
strategy:
matrix:
arch: [ "x86_64", "aarch64" ]
fail-fast: false
runs-on: wolfi-os-builder-${{ matrix.arch }}
# Ensure this is deprivileged, isolated job
# permissions:
container:
image: ghcr.io/wolfi-dev/sdk:latest@sha256:2a939e7a239af196648d2a27add88c3375dd83d0b59d31c7928411011fb022f8
# TODO: Deprivilege
options: |
--cap-add NET_ADMIN --cap-add SYS_ADMIN --device /dev/fuse --security-opt seccomp=unconfined --security-opt apparmor:unconfined
steps:
- uses: actions/checkout@v3
- name: 'Trust the github workspace'
run: |
# This is to avoid fatal errors about "dubious ownership" because we are
# running inside of a container action with the workspace mounted in.
git config --global --add safe.directory "$(pwd)"
# Build with a local key, we'll resign this with the real key later
- name: 'Generate local signing key'
run: |
make local-melange.rsa
# Touch it with the epoch date to convince `make` that we don't need to
# rebuild the targets that depend on this (all)
touch -d @0 local-melange.rsa
- name: 'Prepare package repository'
run: |
# yay wolfi!
apk add gcsfuse
# Set up a gcsfuse RO mount to the public bucket. This is a cheap and
# cheerful way to recreate the make targets (class A HEADs) locally
# without syncing the whole bucket (class A+B).
mkdir -p /gcsfuse/wolfi-registry
gcsfuse -o ro --implicit-dirs --only-dir os wolfi-production-registry-destination /gcsfuse/wolfi-registry
mkdir -p ./packages/${{ matrix.arch }}
# Symlink the gcsfuse mount to ./packages/ to workaround the Makefile CWD assumptions
ln -s /gcsfuse/wolfi-registry/${{ matrix.arch }}/*.apk ./packages/${{ matrix.arch }}/
# Make a copy of the APKINDEX.* since we'll need to write to it on package builds
cp /gcsfuse/wolfi-registry/${{ matrix.arch }}/APKINDEX.* ./packages/${{ matrix.arch }}/
# TODO: Replace this with wolfictl build, since the current make build
# method doesn't trigger new builds for dependent updates.
- name: 'Build Wolfi'
run: |
make \
ARCH=${{ matrix.arch }} \
MELANGE_EXTRA_OPTS="--keyring-append=/gcsfuse/wolfi-registry/wolfi-signing.rsa.pub" \
all -j1
- run: |
# Clean up the symlinks and create an archive for uploading
find ./packages/${{ matrix.arch }} -type l -exec rm -f {} \;
tar -cvzf /tmp/packages-${{ matrix.arch }}.tar.gz ./packages/${{ matrix.arch }}
- name: 'Upload built packages archive to Github Artifacts'
uses: actions/upload-artifact@v3
with:
name: packages-${{ matrix.arch }}
path: /tmp/packages-${{ matrix.arch }}.tar.gz
retention-days: 1 # Low ttl since this is just an intermediary used once
if-no-files-found: warn
upload:
runs-on: ubuntu-latest
needs: build
permissions:
id-token: write
contents: read
container:
# NOTE: This step only signs and uploads, so it doesn't need any privileges
image: ghcr.io/wolfi-dev/sdk:latest@sha256:2a939e7a239af196648d2a27add88c3375dd83d0b59d31c7928411011fb022f8
steps:
- uses: actions/checkout@v3
- name: 'Trust the github workspace'
run: |
# This is to avoid fatal errors about "dubious ownership" because we are
# running inside of a container action with the workspace mounted in.
git config --global --add safe.directory "$(pwd)"
- id: auth
name: 'Authenticate to Google Cloud'
uses: google-github-actions/auth@v0
with:
workload_identity_provider: "projects/618116202522/locations/global/workloadIdentityPools/prod-shared-e350/providers/prod-shared-gha"
service_account: "[email protected]"
- uses: google-github-actions/setup-gcloud@v0
with:
project_id: prod-images-c6e5
- name: 'Download x86_64 package archives'
uses: actions/download-artifact@v3
with:
path: /tmp/artifacts/
name: packages-x86_64
- name: 'Download aarch64 package archives'
uses: actions/download-artifact@v3
with:
path: /tmp/artifacts/
name: packages-aarch64
- run: echo "${{ secrets.MELANGE_RSA }}" > ./wolfi-signing.rsa
- run: |
mkdir -p /etc/apk/keys
cp ./wolfi-signing.rsa.pub /etc/apk/keys/wolfi-signing.rsa.pub
- name: 'Update the APKINDEX'
run: |
for arch in "x86_64" "aarch64"; do
mkdir -p ./packages/${arch}
# Consolidate with the built artifacts
tar xvf /tmp/artifacts/packages-${arch}.tar.gz
# Sign the APK index
melange sign-index -f --signing-key ./wolfi-signing.rsa packages/${arch}/APKINDEX.tar.gz
# Only attempt to sign when *.apk's exist
apks=$(ls ./packages/${arch}/*.apk 2>/dev/null)
if [ -n "$apks" ]; then
# Sign the apks built in the `build` step with the real key
melange sign --signing-key ./wolfi-signing.rsa ./packages/${arch}/*.apk
fi
# NOTE: Everything below is for debugging purposes, we can chose to remove it in the future if we'd like
ls -lah ./packages/${arch}
# Compare the "old" APKIDNEX.tar.gz with the new one
diff <(curl -sfL https://packages.wolfi.dev/os/${arch}/APKINDEX.tar.gz | tar -xOzf - APKINDEX) <(tar -xOzf packages/${arch}/APKINDEX.tar.gz APKINDEX) || true
done
- name: 'Upload the repository to the bucket'
run: |
for arch in "x86_64" "aarch64"; do
# Don't cache the APKINDEX.
gcloud --quiet storage cp \
--cache-control=no-store \
"./packages/${arch}/APKINDEX.tar.gz" "gs://wolfi-production-registry-destination/os/${arch}/"
gcloud --quiet storage cp \
--cache-control=no-store \
"./packages/${arch}/APKINDEX.json" "gs://wolfi-production-registry-destination/os/${arch}/"
# Only attempt to sign when *.apk's exist
apks=$(ls ./packages/${arch}/*.apk 2>/dev/null)
if [ -n "$apks" ]; then
# apks will be cached in CDN for an hour by default.
# Don't upload the object if it already exists.
gcloud --quiet storage cp \
--no-clobber \
"./packages/${arch}/*.apk" "gs://wolfi-production-registry-destination/os/${arch}/"
fi
done
postrun:
name: Build Wolfi OS
runs-on: ubuntu-latest
if: failure()
steps:
- uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0
id: slack
with:
payload: '{"text": "[build-wolfi-os] failure: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"}'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK