Skip to content

Build

Build #398

Workflow file for this run

name: Build
on:
push:
branches:
- main
tags:
- "v*.*.*"
pull_request:
branches:
- main
schedule:
- cron: 0 1 * * 1
workflow_dispatch:
permissions:
contents: write
packages: write
pull-requests: read
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # fetch-depth is required
- uses: wagoid/commitlint-github-action@v5
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # fetch-depth is required
- name: Set up Go without go.mod
uses: actions/setup-go@v5
if: ${{ hashFiles('go.mod') == '' }}
with:
check-latest: true
- name: Set up Go with go.mod
uses: actions/setup-go@v5
if: ${{ hashFiles('go.mod') != '' }}
with:
go-version-file: go.mod
- uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Setup JS
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: |
go install ./... || true
npm ci || true
- uses: pre-commit/action@v3.0.1
list_images:
runs-on: ubuntu-latest
outputs:
list: ${{ steps.tags.outputs.list }}
steps:
- uses: actions/checkout@v4
- name: Generate Docker tag
id: tags
run: |
echo "list={\"img\": $(jq -ncR '[inputs]' <<< $(ls -d images/* | grep -v '/base'))}" >> "$GITHUB_OUTPUT"
list_runners:
runs-on: ubuntu-latest
outputs:
list: ${{ steps.runners.outputs.list }}
steps:
- id: runners
run: |-
if [ ${{ github.ref == 'refs/heads/main' }} = "true" ]; then
echo "list={\"runner\":[{\"image\": \"ubuntu-latest\", \"platform\": \"linux/amd64\" }, { \"image\": \"ubuntu-24.04-arm\", \"platform\": \"linux/arm64\" }]}" >> "$GITHUB_OUTPUT"
else
echo "list={\"runner\":[{\"image\": \"ubuntu-latest\", \"platform\": \"linux/amd64\" }]}" >> "$GITHUB_OUTPUT"
fi
base:
runs-on: ${{ matrix.runner.image }}
needs:
- commitlint
- list_runners
- pre-commit
outputs:
docker_registry: ${{ steps.tags.outputs.docker_registry }}
tag: ${{ steps.tags.outputs.tag }}
strategy:
fail-fast: true
matrix: ${{ fromJSON(needs.list_runners.outputs.list) }}
steps:
- uses: actions/checkout@v4
- name: Setup JS
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate Docker tag
id: tags
run: |
echo "docker_registry=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"
echo "tag=$(date --iso-8601)" >> "$GITHUB_OUTPUT"
- name: Install Dev Container CLI
run: |
npm install -g @devcontainers/cli
devcontainer --version
- name: Build Dev Container
run: |
ADDITIONAL_BUILD_COMMANDS=""
if [ ${{ github.ref == 'refs/heads/main' }} = "true" ]; then
ADDITIONAL_BUILD_COMMANDS="--push"
fi
devcontainer build \
${ADDITIONAL_BUILD_COMMANDS} \
--image-name=${{ steps.tags.outputs.docker_registry }}/base:${{ github.sha }}-${{ matrix.runner.image }} \
--workspace-folder=images/base
if [ ${{ github.ref == 'refs/heads/main' }} = "false" ]; then
echo "Saving base image"
docker save ${{ steps.tags.outputs.docker_registry }}/base:${{ github.sha }}-${{ matrix.runner.image }} -o base.tar.gz
fi
- name: Archive Docker image
uses: actions/upload-artifact@v4
if: ${{ github.ref != 'refs/heads/main' }}
with:
name: docker-image-${{ matrix.runner.image }}
path: base.tar.gz
if-no-files-found: error
retention-days: 1
compression-level: 0
overwrite: true
base_manifest:
runs-on: ubuntu-latest
needs:
- base
- list_runners
- list_images
outputs:
matrix: ${{ steps.matrix.outputs.matrix }}
steps:
- name: Generate image matrix
id: matrix
run: |
echo ${{ toJson(needs.list_runners.outputs.list) }} | jq -rc > runners.json
echo ${{ toJson(needs.list_images.outputs.list) }} | jq -rc > images.json
echo "matrix=$(jq -c -s 'map(to_entries) | flatten | group_by(.key) | map({key: .[0].key, value: map(.value) | add}) | from_entries' <<< "$(cat runners.json)$(cat images.json)")" >> "$GITHUB_OUTPUT"
inputs=""
for row in $(cat runners.json | jq -rc '.runner[] | @base64'); do
inputs="${inputs},${{ needs.base.outputs.docker_registry }}/base:${{ github.sha }}-$(echo "${row}" | base64 -d | jq -r '.image')"
done
echo "inputs=${inputs}" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: Noelware/docker-manifest-action@v1
if: ${{ github.ref == 'refs/heads/main' }}
with:
inputs: ${{ steps.matrix.outputs.inputs }}
tags: ${{ needs.base.outputs.docker_registry }}/base:${{ needs.base.outputs.tag }},${{ needs.base.outputs.docker_registry }}/base:latest
push: true
annotations: index:org.opencontainers.image.source=https://github.com/${{ github.repository }}
images:
runs-on: ${{ matrix.runner.image }}
needs:
- base
- base_manifest
strategy:
fail-fast: true
matrix: ${{ fromJSON(needs.base_manifest.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- name: Setup JS
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate Docker tag
id: tags
run: |
echo "name=$(echo ${{ matrix.img }} | sed 's/images\///' )" >> "$GITHUB_OUTPUT"
- name: Install Dev Container CLI
run: |
npm install -g @devcontainers/cli
devcontainer --version
- name: Import Docker image
uses: actions/download-artifact@v4
if: ${{ github.ref != 'refs/heads/main' }}
with:
name: docker-image-${{ matrix.runner.image }}
- name: Build Dev Container
run: |
ADDITIONAL_BUILD_COMMANDS=""
if [ ${{ github.ref == 'refs/heads/main' }} = "true" ]; then
ADDITIONAL_BUILD_COMMANDS="--push"
else
echo "Importing image from cache"
docker import base.tar.gz ${{ needs.base.outputs.docker_registry }}/base
fi
devcontainer build \
${ADDITIONAL_BUILD_COMMANDS} \
--image-name=${{ needs.base.outputs.docker_registry }}/${{ steps.tags.outputs.name }}:${{ github.sha }}-${{ matrix.runner.image }} \
--workspace-folder=${{ matrix.img }}
images_manifest:
runs-on: ubuntu-latest
needs:
- base
- list_images
- list_runners
- images
strategy:
fail-fast: true
matrix: ${{ fromJSON(needs.list_images.outputs.list) }}
steps:
- name: Generate Docker tag
id: tags
run: |
img_name=$(echo ${{ matrix.img }} | sed 's/images\///')
echo "name=${img_name}" >> "$GITHUB_OUTPUT"
echo ${{ toJson(needs.list_runners.outputs.list) }} | jq -rc > runners.json
inputs=""
for row in $(cat runners.json | jq -rc '.runner[] | @base64'); do
inputs="${inputs},${{ needs.base.outputs.docker_registry }}/${img_name}:${{ github.sha }}-$(echo "${row}" | base64 -d | jq -r '.image')"
done
echo "inputs=${inputs}" >> "$GITHUB_OUTPUT"
echo "name=${img_name}" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: Noelware/docker-manifest-action@v1
if: ${{ github.ref == 'refs/heads/main' }}
with:
inputs: ${{ steps.tags.outputs.inputs }}
tags: ${{ needs.base.outputs.docker_registry }}/${{ steps.tags.outputs.name }}:${{ needs.base.outputs.tag }},${{ needs.base.outputs.docker_registry }}/${{ steps.tags.outputs.name }}:latest
push: true
annotations: index:org.opencontainers.image.source=https://github.com/${{ github.repository }}