Files
firezone/.github/workflows/_build_artifacts.yml
Jamil c6b0b0a922 ci: Release 1.3.0 for Internet Resource (#6503)
This publishes the 1.3.0 clients and gateways so that Internet Resources
will work.

The feature is still disabled for the Stripe plans until we publish the
launch post. Select customers have the feature enabled.

Closes #2667
2024-08-30 01:21:34 -07:00

409 lines
17 KiB
YAML

name: Build Artifacts
run-name: Triggered from ${{ github.event_name }} by ${{ github.actor }}
on:
workflow_call:
inputs:
image_prefix:
description: |
The prefix to prepend to the image name to prevent SHA conflicts.
* Use "debug" to build debug binaries inside debug stage images + with debug tooling installed.
* Use "perf" to build release binaries inside debug stage images + with debug tooling installed.
* Leave blank to build release binaries inside release stage images.
required: false
type: string
sha:
required: false
type: string
default: ${{ github.sha }}
profile:
description: "The Rust profile to build data plane components with"
required: true
type: string
stage:
description: "The stage of the data plane component images to build"
required: true
type: string
outputs:
client_image:
description: "The client image that was built"
value: ${{ jobs.data-plane.outputs.client_image }}
relay_image:
description: "The relay image that was built"
value: ${{ jobs.data-plane.outputs.relay_image }}
gateway_image:
description: "The gateway image that was built"
value: ${{ jobs.data-plane.outputs.gateway_image }}
http_test_server_image:
description: "The http_test_server image that was built"
value: ${{ jobs.data-plane.outputs.http_test_server_image }}
permissions:
# write permission is required to create a github release
contents: write
id-token: write
jobs:
control-plane:
name: ${{ matrix.image_name }}
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- image_name: domain
target: runtime
build-args: |
APPLICATION_NAME=domain
GIT_SHA=${{ inputs.sha }}
- image_name: api
target: runtime
build-args: |
APPLICATION_NAME=api
GIT_SHA=${{ inputs.sha }}
- image_name: web
target: runtime
build-args: |
APPLICATION_NAME=web
GIT_SHA=${{ inputs.sha }}
- image_name: elixir
target: compiler
build-args: |
APPLICATION_NAME=api
GIT_SHA=${{ inputs.sha }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.sha }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
# We are overriding the default buildkit version being used by Buildx. We need buildkit >= 12.0 and currently BuildX
# supports v0.11.6 https://github.com/docker/buildx/blob/b8739d74417f86aa8fc9aafb830a8ba656bdef0e/Dockerfile#L9.
# We should for any updates on buildx and on the setup-buildx-action itself.
driver-opts: |
image=moby/buildkit:v0.15.1
- uses: ./.github/actions/gcp-docker-login
id: login
with:
project: firezone-staging
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images:
${{ steps.login.outputs.registry }}/firezone/${{matrix.image_name }}
tags: |
type=raw,value=${{ inputs.sha }}
- name: Sanitize github.ref_name
run: |
# `ref_name` contains `/`, '_' or '=' which is not a valid docker image tag
REF="${{ github.ref_name }}"
CACHE_TAG="${REF//[\/_=]/-}"
echo "CACHE_TAG=$CACHE_TAG" >> "$GITHUB_ENV"
- name: Build and push control plane images
id: build
uses: docker/build-push-action@v6
with:
build-args: ${{ matrix.build-args }}
target: ${{ matrix.target }}
context: elixir
cache-from: |
type=registry,ref=${{ steps.login.outputs.registry }}/cache/${{ matrix.image_name }}:${{ env.CACHE_TAG }}
type=registry,ref=${{ steps.login.outputs.registry }}/cache/${{ matrix.image_name }}:main
cache-to: |
type=registry,ref=${{steps.login.outputs.registry}}/cache/${{ matrix.image_name}}:${{ env.CACHE_TAG }},mode=max
push: true
tags: |
${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ inputs.sha }}
${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ env.CACHE_TAG }}
data-plane:
name: ${{ matrix.name.image_name }}-${{ matrix.arch.shortname }}
runs-on: ubuntu-22.04
defaults:
run:
working-directory: rust
strategy:
fail-fast: false
matrix:
# Copy input vars to matrix vars to conditionally exclude them
image_prefix:
- ${{ inputs.image_prefix }}
stage:
- ${{ inputs.stage }}
# Syntax is weird because https://github.com/actions/runner/issues/1512
exclude:
# Exclude debug builds for non-amd64 targets since they won't be used.
- {stage: debug, arch: {platform: linux/arm/v7}}
- {stage: debug, arch: {platform: linux/arm64}}
# Exclude http-test-server from perf image builds
- {image_prefix: perf, name: {package: http-test-server}}
arch:
- target: x86_64-unknown-linux-musl
shortname: x86_64
platform: linux/amd64
- target: aarch64-unknown-linux-musl # E.g. AWS Graviton
shortname: aarch64
platform: linux/arm64
- target: armv7-unknown-linux-musleabihf # E.g. Raspberry Pi
platform: linux/arm/v7
shortname: armv7
name:
- package: firezone-headless-client
artifact: firezone-client-headless-linux
image_name: client
# mark:next-headless-version
release_name: headless-client-1.3.1
# mark:next-headless-version
version: 1.3.1
- package: firezone-relay
artifact: firezone-relay
image_name: relay
- package: firezone-gateway
artifact: firezone-gateway
image_name: gateway
# mark:next-gateway-version
release_name: gateway-1.3.1
# mark:next-gateway-version
version: 1.3.1
- package: http-test-server
artifact: http-test-server
image_name: http-test-server
env:
BINARY_DEST_PATH: ${{ matrix.name.artifact }}_${{ matrix.name.version }}_${{ matrix.arch.shortname }}
outputs:
client_image: ${{ steps.image-name.outputs.client_image }}
relay_image: ${{ steps.image-name.outputs.relay_image }}
gateway_image: ${{ steps.image-name.outputs.gateway_image }}
http_test_server_image: ${{ steps.image-name.outputs.http-test-server_image }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.sha }}
- uses: ./.github/actions/setup-rust
with:
targets: ${{ matrix.arch.target }}
# Cross doesn't support scccache without a lot of work
cache_backend: github
# Cache needs to be scoped per OS version and target since cross seems to clobber the cache
key: ubuntu-22.04-${{ matrix.arch.target }}
- uses: taiki-e/install-action@v2
with:
tool: cross
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build binaries
run: |
set -xe
if [[ "${{ inputs.profile }}" == "release" ]]; then
PROFILE="--release"
else
PROFILE=""
fi
cross build $PROFILE -p ${{ matrix.name.package }} --target ${{ matrix.arch.target }}
# Used for Docker images
cp target/${{ matrix.arch.target }}/${{ inputs.profile }}/${{ matrix.name.package }} ${{ matrix.name.package }}
- name: Upload Release Assets
if: ${{ inputs.profile == 'release' && matrix.stage == 'release' && matrix.name.release_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -xe
# Only clobber existing release assets if the release is a draft
is_draft=$(gh release view ${{ matrix.name.release_name }} --json isDraft --jq '.isDraft' | tr -d '\n')
if [[ "$is_draft" == "true" ]]; then
clobber="--clobber"
else
clobber=""
fi
# Used for release artifact
cp target/${{ matrix.arch.target }}/${{ inputs.profile }}/${{ matrix.name.package }} $BINARY_DEST_PATH
sha256sum $BINARY_DEST_PATH > $BINARY_DEST_PATH.sha256sum.txt
gh release upload ${{ matrix.name.release_name }} \
${{ env.BINARY_DEST_PATH }} \
${{ env.BINARY_DEST_PATH }}.sha256sum.txt \
$clobber \
--repo ${{ github.repository }}
- name: Authenticate to Google Cloud
id: auth
if: ${{ inputs.profile == 'release' && matrix.stage == 'release' && contains(fromJSON('["gateway", "client"]'), matrix.name.image_name) }}
uses: google-github-actions/auth@v2
with:
workload_identity_provider: "projects/397012414171/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions"
service_account: "github-actions@github-iam-387915.iam.gserviceaccount.com"
export_environment_variables: true
create_credentials_file: true
- name: Copy binaries to Google Cloud Storage
if: ${{ inputs.profile == 'release' && matrix.stage == 'release' && contains(fromJSON('["gateway", "client"]'), matrix.name.image_name) }}
run: |
gcloud storage cp \
${BINARY_DEST_PATH} \
gs://firezone-staging-artifacts/firezone-${{ matrix.name.image_name }}/${{ inputs.sha }}/${{ matrix.arch.shortname }}
gcloud storage cp \
${BINARY_DEST_PATH}.sha256sum.txt \
gs://firezone-staging-artifacts/firezone-${{ matrix.name.image_name }}/${{ inputs.sha }}/${{ matrix.arch.shortname }}.sha256sum.txt
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
# We are overriding the default buildkit version being used by Buildx. We need buildkit >= 12.0 and currently BuildX
# supports v0.11.6 https://github.com/docker/buildx/blob/b8739d74417f86aa8fc9aafb830a8ba656bdef0e/Dockerfile#L9.
# We should for any updates on buildx and on the setup-buildx-action itself.
driver-opts: |
image=moby/buildkit:v0.15.1
- uses: ./.github/actions/gcp-docker-login
id: login
with:
project: firezone-staging
- name: Build Version Tags
run: |
set -xe
version="${{ matrix.name.version }}"
MAJOR_VERSION="${version%%.*}"
MAJOR_MINOR_VERSION="${version%.*}"
echo "MAJOR_VERSION=${MAJOR_VERSION}" >> $GITHUB_ENV
echo "MAJOR_MINOR_VERSION=${MAJOR_MINOR_VERSION}" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images:
${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_prefix && format('{0}/', matrix.image_prefix) || '' }}${{ matrix.name.image_name }}
# We only version client and gateway
tags: |
type=raw,value=latest
type=raw,value=${{ inputs.sha }}
${{ matrix.name.version && format('type=raw,value={0}', matrix.name.version) }}
${{ matrix.name.version && format('type=raw,value={0}-{1}', matrix.name.version, inputs.sha) }}
${{ matrix.name.version && format('type=raw,value={0}', env.MAJOR_VERSION) }}
${{ matrix.name.version && format('type=raw,value={0}', env.MAJOR_MINOR_VERSION) }}
- name: Sanitize github.ref_name
run: |
# `ref_name` contains `/`, '_' or '=' which is not a valid docker image tag
REF="${{ github.ref_name }}"
CACHE_TAG="${REF//[\/_=]/-}"
echo "CACHE_TAG=$CACHE_TAG" >> "$GITHUB_ENV"
- name: Build Docker images
id: build
uses: docker/build-push-action@v6
with:
platforms: ${{ matrix.arch.platform }}
build-args: |
PACKAGE=${{ matrix.name.package }}
TARGET=${{ matrix.arch.target }}
context: rust
cache-from: |
type=registry,ref=${{ steps.login.outputs.registry }}/cache/${{ matrix.name.image_name }}:${{ env.CACHE_TAG }}
type=registry,ref=${{ steps.login.outputs.registry }}/cache/${{ matrix.name.image_name }}:main
cache-to: |
type=registry,ref=${{ steps.login.outputs.registry }}/cache/${{ matrix.name.image_name }}:${{ env.CACHE_TAG }},mode=max
target: ${{ matrix.stage }}
outputs:
type=image,name=${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_prefix && format('{0}/', matrix.image_prefix) || '' }}${{ matrix.name.image_name }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p /tmp/digests/${{ matrix.name.image_name }}
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${{ matrix.name.image_name }}/${digest#sha256:}"
- name: Upload digest artifact
uses: actions/upload-artifact@v4
with:
overwrite: true
name: ${{ matrix.image_prefix && format('{0}-', matrix.image_prefix) || '' }}${{ matrix.name.image_name }}-${{ inputs.sha }}-digest-${{ matrix.arch.shortname }}
path: /tmp/digests/${{ matrix.name.image_name }}
if-no-files-found: error
retention-days: 1
- name: Output image name
id: image-name
run: echo "${{ matrix.name.image_name }}_image=${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_prefix && format('{0}/', matrix.image_prefix) || '' }}${{ matrix.name.image_name }}" >> $GITHUB_OUTPUT
merge-docker-artifacts:
name: merge-${{ matrix.image.name }}
needs: data-plane
if: ${{ always() }}
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
# Copy input vars to matrix vars to conditionally exclude them
image_prefix:
- ${{ inputs.image_prefix }}
# Exclude http-test-server from perf image builds
exclude:
- {image_prefix: perf, image: {name: http-test-server}}
image:
- name: relay
- name: gateway
# mark:next-gateway-version
version: 1.3.1
- name: client
# mark:next-client-version
version: 1.0.6
- name: http-test-server
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.sha }}
- uses: ./.github/actions/gcp-docker-login
id: login
with:
project: firezone-staging
- name: Download digests
uses: actions/download-artifact@v4
with:
pattern: ${{ matrix.image_prefix && format('{0}-', matrix.image_prefix) || '' }}${{ matrix.image.name }}-${{ inputs.sha }}-digest-*
merge-multiple: true
path: /tmp/digests/${{ matrix.image.name }}
- name: Display structure of downloaded artifacts
run: ls -R /tmp/digests
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
# We are overriding the default buildkit version being used by Buildx. We need buildkit >= 12.0 and currently BuildX
# supports v0.11.6 https://github.com/docker/buildx/blob/b8739d74417f86aa8fc9aafb830a8ba656bdef0e/Dockerfile#L9.
# We should for any updates on buildx and on the setup-buildx-action itself.
driver-opts: |
image=moby/buildkit:v0.15.1
- name: Build Version Tags
run: |
set -xe
version="${{ matrix.image.version }}"
MAJOR_VERSION="${version%%.*}"
MAJOR_MINOR_VERSION="${version%.*}"
echo "MAJOR_VERSION=${MAJOR_VERSION}" >> $GITHUB_ENV
echo "MAJOR_MINOR_VERSION=${MAJOR_MINOR_VERSION}" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images:
${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_prefix && format('{0}/', matrix.image_prefix) || '' }}${{ matrix.image.name }}
tags: |
type=raw,value=latest
type=raw,value=${{ inputs.sha }}
${{ matrix.image.version && format('type=raw,value={0}', matrix.image.version) }}
${{ matrix.image.version && format('type=raw,value={0}-{1}', matrix.image.version, inputs.sha) }}
${{ matrix.image.version && format('type=raw,value={0}', env.MAJOR_VERSION) }}
${{ matrix.image.version && format('type=raw,value={0}', env.MAJOR_MINOR_VERSION) }}
- name: Create manifest list and push
working-directory: /tmp/digests/${{ matrix.image.name }}
run: |
tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")
sources=$(printf '${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_prefix && format('{0}/', matrix.image_prefix) || '' }}${{ matrix.image.name }}@sha256:%s ' *)
echo "$sources"
docker buildx imagetools create $tags $sources
docker buildx imagetools inspect "${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_prefix && format('{0}/', matrix.image_prefix) || '' }}${{ matrix.image.name }}"