From 448499b13ef27505c79a143ce6e72d579113deb4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sun, 12 Oct 2025 18:40:25 +1100 Subject: [PATCH] ci: only create data-plane draft release on trigger (#10542) Right now, draft releases for Gateways and headless-clients are created on each merge to main. For all other components, we only create those when we trigger the workflow for a specific commit. To align this functionality, we split the `_build_artifacts.yml` workflow into two: - `_control-plane.yml` - `_data-plane.yml` Apart from the `sha` input, all inputs only concern the data-plane, therefore massively simplifying the control-plane workflow. Additionally, the control-plane also doesn't have a manual trigger because its artifacts never get released on GitHub. Resolves: #10541 --- .github/workflows/_control-plane.yml | 99 +++++++++++++++++ .../{_build_artifacts.yml => _data-plane.yml} | 105 +++++------------- .github/workflows/_kotlin.yml | 2 +- .github/workflows/_swift.yml | 2 +- .github/workflows/_tauri.yml | 2 +- .github/workflows/cd.yml | 12 +- .github/workflows/ci.yml | 72 +++++------- 7 files changed, 160 insertions(+), 134 deletions(-) create mode 100644 .github/workflows/_control-plane.yml rename .github/workflows/{_build_artifacts.yml => _data-plane.yml} (84%) diff --git a/.github/workflows/_control-plane.yml b/.github/workflows/_control-plane.yml new file mode 100644 index 000000000..64f83928f --- /dev/null +++ b/.github/workflows/_control-plane.yml @@ -0,0 +1,99 @@ +name: Build control plane +run-name: Triggered from ${{ github.event_name }} by ${{ github.actor }} +on: + workflow_call: + inputs: + sha: + required: false + type: string + default: ${{ github.sha }} + +permissions: + id-token: write + packages: write + +jobs: + control-plane: + name: ${{ matrix.image_name }} + runs-on: ubuntu-24.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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + ref: ${{ inputs.sha }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + - uses: ./.github/actions/ghcr-docker-login + id: login + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + - name: Docker meta + id: meta + uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 + 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" + # PRs & non-main branches: read-only cache + - name: Build and push control plane images (read-only cache) + if: ${{ github.ref != 'refs/heads/main' }} + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + build-args: ${{ matrix.build-args }} + target: ${{ matrix.target }} + context: elixir + cache-from: | + type=gha,scope=${{ matrix.image_name }}:${{ env.CACHE_TAG }} + type=gha,scope=${{ matrix.image_name }}:main + # no cache-to here -> read-only + push: true + tags: | + ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ inputs.sha }} + ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ env.CACHE_TAG }} + + # main: read/write cache + - name: Build and push control plane images (read/write cache) + if: ${{ github.ref == 'refs/heads/main' }} + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + build-args: ${{ matrix.build-args }} + target: ${{ matrix.target }} + context: elixir + cache-from: | + type=gha,scope=${{ matrix.image_name }}:${{ env.CACHE_TAG }} + type=gha,scope=${{ matrix.image_name }}:main + cache-to: | + type=gha,scope=${{ matrix.image_name }}:${{ env.CACHE_TAG }},mode=max,ignore-error=true + push: true + tags: | + ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ inputs.sha }} + ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ env.CACHE_TAG }} diff --git a/.github/workflows/_build_artifacts.yml b/.github/workflows/_data-plane.yml similarity index 84% rename from .github/workflows/_build_artifacts.yml rename to .github/workflows/_data-plane.yml index 7afd0451b..b90e8b002 100644 --- a/.github/workflows/_build_artifacts.yml +++ b/.github/workflows/_data-plane.yml @@ -1,6 +1,7 @@ -name: Build Artifacts +name: Build data plane run-name: Triggered from ${{ github.event_name }} by ${{ github.actor }} on: + workflow_dispatch: workflow_call: inputs: image_prefix: @@ -44,94 +45,37 @@ permissions: packages: write jobs: - control-plane: - name: ${{ matrix.image_name }} + update-release-draft: + name: update-release-draft-${{ matrix.config_name }} runs-on: ubuntu-24.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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - ref: ${{ inputs.sha }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - uses: ./.github/actions/ghcr-docker-login - id: login - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - - name: Docker meta - id: meta - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 - 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" - # PRs & non-main branches: read-only cache - - name: Build and push control plane images (read-only cache) - if: ${{ github.ref != 'refs/heads/main' }} - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - build-args: ${{ matrix.build-args }} - target: ${{ matrix.target }} - context: elixir - cache-from: | - type=gha,scope=${{ matrix.image_name }}:${{ env.CACHE_TAG }} - type=gha,scope=${{ matrix.image_name }}:main - # no cache-to here -> read-only - push: true - tags: | - ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ inputs.sha }} - ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ env.CACHE_TAG }} + # mark:next-gateway-version + - release_name: gateway-1.4.17 + config_name: release-drafter-gateway.yml + # mark:next-headless-version + - release_name: headless-client-1.5.4 + config_name: release-drafter-headless-client.yml - # main: read/write cache - - name: Build and push control plane images (read/write cache) - if: ${{ github.ref == 'refs/heads/main' }} - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + steps: + - uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 + if: "${{ github.event_name == 'workflow_dispatch' && github.ref_name == 'main' }}" + id: update-release-draft with: - build-args: ${{ matrix.build-args }} - target: ${{ matrix.target }} - context: elixir - cache-from: | - type=gha,scope=${{ matrix.image_name }}:${{ env.CACHE_TAG }} - type=gha,scope=${{ matrix.image_name }}:main - cache-to: | - type=gha,scope=${{ matrix.image_name }}:${{ env.CACHE_TAG }},mode=max,ignore-error=true - push: true - tags: | - ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ inputs.sha }} - ${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ env.CACHE_TAG }} + config-name: ${{ matrix.config_name }} + tag: ${{ matrix.release_name }} + version: ${{ matrix.release_name }} + name: ${{ matrix.release_name }} + commitish: ${{ github.sha }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} data-plane-windows: name: client-windows-${{ matrix.target }} if: ${{ inputs.image_prefix != 'perf' }} # Perf testing happens only on Linux + needs: update-release-draft runs-on: windows-2022 defaults: run: @@ -185,7 +129,7 @@ jobs: AZURE_CERT_NAME: ${{ secrets.AZURE_CERT_NAME }} run: ../scripts/build/sign.sh "$ARTIFACT_PATH" - name: Upload Release Assets - if: ${{ inputs.profile == 'release' && inputs.stage == 'release' && matrix.release_name }} + if: ${{ inputs.profile == 'release' && inputs.stage == 'release' && matrix.release_name && github.event_name == 'workflow_dispatch' && github.ref_name == 'main' }} shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -194,6 +138,7 @@ jobs: data-plane-linux: name: ${{ matrix.name.image_name }}-${{ matrix.arch.shortname }} runs-on: ubuntu-24.04 + needs: update-release-draft defaults: run: working-directory: rust @@ -351,7 +296,7 @@ jobs: --no-progress \ --connection-string "${{ secrets.AZURERM_ARTIFACTS_CONNECTION_STRING }}" - name: Upload Release Assets - if: ${{ inputs.profile == 'release' && matrix.stage == 'release' && matrix.name.release_name }} + if: ${{ inputs.profile == 'release' && matrix.stage == 'release' && matrix.name.release_name && github.event_name == 'workflow_dispatch' && github.ref_name == 'main' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | diff --git a/.github/workflows/_kotlin.yml b/.github/workflows/_kotlin.yml index 267dfe5ef..207dd8b0a 100644 --- a/.github/workflows/_kotlin.yml +++ b/.github/workflows/_kotlin.yml @@ -1,4 +1,4 @@ -name: Kotlin +name: Build Android app on: workflow_call: workflow_dispatch: diff --git a/.github/workflows/_swift.yml b/.github/workflows/_swift.yml index 3398f276f..1d56c2dfa 100644 --- a/.github/workflows/_swift.yml +++ b/.github/workflows/_swift.yml @@ -1,4 +1,4 @@ -name: Swift +name: Build macOS/iOS app on: workflow_call: workflow_dispatch: diff --git a/.github/workflows/_tauri.yml b/.github/workflows/_tauri.yml index 6b3289b85..0dd788383 100644 --- a/.github/workflows/_tauri.yml +++ b/.github/workflows/_tauri.yml @@ -1,4 +1,4 @@ -name: Tauri +name: Build Tauri app on: workflow_call: workflow_dispatch: diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 0d5a11767..3a36f2457 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -9,8 +9,8 @@ on: jobs: # Builds images that match what's default in docker-compose.yml for # local development. - build-dev-images: - uses: ./.github/workflows/_build_artifacts.yml + build-data-plane-dev-images: + uses: ./.github/workflows/_data-plane.yml secrets: inherit with: image_prefix: "dev" @@ -18,14 +18,18 @@ jobs: profile: "debug" # Builds debug images with release binaries for compatibility tests in case the merge_group was skipped. - build-test-images: - uses: ./.github/workflows/_build_artifacts.yml + build-data-plane-test-images: + uses: ./.github/workflows/_data-plane.yml secrets: inherit with: image_prefix: "debug" stage: "debug" profile: "release" + build-control-plane-images: + uses: ./.github/workflows/_control-plane.yml + secrets: inherit + # Re-run CI checks to make sure everything's green, since "Merging as administrator" # won't trigger these in the merge group. ci: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2add9c6f..9183ecd0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: run: | set -e - jobs="static-analysis,elixir,rust,tauri,kotlin,swift,codeql,build-artifacts,build-perf-artifacts"; + jobs="static-analysis,elixir,rust,tauri,kotlin,swift,codeql,control-plane,data-plane,data-plane-perf"; # For workflow_dispatch or workflow_call, run all jobs if [ "${{ github.event_name }}" = "workflow_dispatch" ] || [ "${{ github.event_name }}" = "workflow_call" ]; then @@ -87,7 +87,7 @@ jobs: jobs="static-analysis" # Always run static-analysis if grep -q '^rust/' changed_files.txt; then - jobs="${jobs},rust,kotlin,swift,build-artifacts,build-perf-artifacts" + jobs="${jobs},rust,kotlin,swift,control-plane,data-plane,data-plane-perf" fi if grep -q '^rust/gui-client/' changed_files.txt; then jobs="${jobs},tauri" @@ -96,7 +96,7 @@ jobs: jobs="${jobs},tauri" fi if grep -q '^elixir/' changed_files.txt; then - jobs="${jobs},elixir,codeql,build-artifacts" + jobs="${jobs},elixir,codeql,control-plane,data-plane" fi if grep -q '^kotlin/' changed_files.txt; then jobs="${jobs},kotlin" @@ -108,7 +108,7 @@ jobs: jobs="${jobs},codeql" fi if grep -q '^scripts/tests/' changed_files.txt; then - jobs="${jobs},build-artifacts,build-perf-artifacts" + jobs="${jobs},control-plane,data-plane,data-plane-perf" fi echo "jobs_to_run=$jobs" >> "$GITHUB_OUTPUT" @@ -186,38 +186,16 @@ jobs: uses: ./.github/workflows/_codeql.yml secrets: inherit - update-release-draft: - name: update-release-draft-${{ matrix.config_name }} - runs-on: ubuntu-24.04 - strategy: - fail-fast: false - matrix: - include: - # mark:next-gateway-version - - release_name: gateway-1.4.17 - config_name: release-drafter-gateway.yml - # mark:next-headless-version - - release_name: headless-client-1.5.4 - config_name: release-drafter-headless-client.yml + control-plane: + needs: planner + if: contains(needs.planner.outputs.jobs_to_run, 'control-plane') + uses: ./.github/workflows/_control-plane.yml + secrets: inherit - steps: - - uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 - # Only draft releases on merges to main - if: ${{ github.ref_name == 'main' }} - id: update-release-draft - with: - config-name: ${{ matrix.config_name }} - tag: ${{ matrix.release_name }} - version: ${{ matrix.release_name }} - name: ${{ matrix.release_name }} - commitish: ${{ github.sha }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - build-artifacts: - needs: [update-release-draft, planner] - if: contains(needs.planner.outputs.jobs_to_run, 'build-artifacts') - uses: ./.github/workflows/_build_artifacts.yml + data-plane: + needs: planner + if: contains(needs.planner.outputs.jobs_to_run, 'data-plane') + uses: ./.github/workflows/_data-plane.yml secrets: inherit with: # Build debug/ on PRs and merge group, no prefix for production release images @@ -225,10 +203,10 @@ jobs: profile: ${{ inputs.profile || 'debug' }} stage: ${{ inputs.stage || 'debug' }} - build-perf-artifacts: - needs: [update-release-draft, planner] - if: contains(needs.planner.outputs.jobs_to_run, 'build-perf-artifacts') - uses: ./.github/workflows/_build_artifacts.yml + data-plane-perf: + needs: planner + if: contains(needs.planner.outputs.jobs_to_run, 'data-plane-perf') + uses: ./.github/workflows/_data-plane.yml secrets: inherit with: sha: ${{ github.sha }} @@ -238,13 +216,13 @@ jobs: integration-tests: uses: ./.github/workflows/_integration_tests.yml - needs: build-artifacts + needs: [control-plane, data-plane] secrets: inherit with: - gateway_image: ${{ needs.build-artifacts.outputs.gateway_image }} - client_image: ${{ needs.build-artifacts.outputs.client_image }} - relay_image: ${{ needs.build-artifacts.outputs.relay_image }} - http_test_server_image: ${{ needs.build-artifacts.outputs.http_test_server_image }} + gateway_image: ${{ needs.data-plane.outputs.gateway_image }} + client_image: ${{ needs.data-plane.outputs.client_image }} + relay_image: ${{ needs.data-plane.outputs.relay_image }} + http_test_server_image: ${{ needs.data-plane.outputs.http_test_server_image }} compatibility-tests: strategy: @@ -254,7 +232,7 @@ jobs: - image: "ghcr.io/firezone/client" tag: "latest" gateway: - - image: ${{ needs.build-artifacts.outputs.gateway_image }} + - image: ${{ needs.data-plane.outputs.gateway_image }} tag: ${{ github.sha }} ci-name: sha - image: "ghcr.io/firezone/gateway" @@ -266,7 +244,7 @@ jobs: if: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }} name: compatibility-tests-client(${{ matrix.client.tag }})-gateway(${{ matrix.gateway.ci-name }}) uses: ./.github/workflows/_integration_tests.yml - needs: build-artifacts + needs: [control-plane, data-plane] secrets: inherit with: gateway_image: ${{ matrix.gateway.image }} @@ -276,7 +254,7 @@ jobs: perf-tests: name: perf-tests - needs: build-perf-artifacts + needs: [control-plane, data-plane-perf] runs-on: ubuntu-24.04 permissions: contents: read