mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-03-22 04:42:03 +00:00
- Uses infra we [set up previously](https://portal.azure.com/#@firezoneinc.onmicrosoft.com/resource/subscriptions/43767d16-5744-41af-ab38-6323d54b9b7d/resourceGroups/Default/providers/Microsoft.KeyVault/vaults/firezone-code-signing/overview) in Azure for codesigning. - Cert is currently expired so this is likely to fail. Currently pending renewal with GlobalSign - May need a few more pushes to `main` to troubleshoot issues since this is run in CD Fixes #3230
365 lines
12 KiB
YAML
365 lines
12 KiB
YAML
name: Continuous Integration
|
|
on:
|
|
pull_request:
|
|
merge_group:
|
|
types: [checks_requested]
|
|
workflow_call:
|
|
|
|
# Cancel old workflow runs if new code is pushed
|
|
concurrency:
|
|
group: "ci-${{ github.workflow }}-${{ github.ref }}"
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
elixir:
|
|
uses: ./.github/workflows/_elixir.yml
|
|
rust:
|
|
uses: ./.github/workflows/_rust.yml
|
|
secrets: inherit
|
|
kotlin:
|
|
uses: ./.github/workflows/_kotlin.yml
|
|
secrets: inherit
|
|
swift:
|
|
uses: ./.github/workflows/_swift.yml
|
|
secrets: inherit
|
|
static-analysis:
|
|
uses: ./.github/workflows/_static-analysis.yml
|
|
terraform:
|
|
uses: ./.github/workflows/_terraform.yml
|
|
secrets: inherit
|
|
codeql:
|
|
uses: ./.github/workflows/_codeql.yml
|
|
secrets: inherit
|
|
|
|
# We could build these in GCP with Cloud Build, but for now it's
|
|
# less overhead to keep things in GH actions. See work on building these
|
|
# in GCP with Cloud Build: https://github.com/firezone/firezone/pull/2234
|
|
build-images:
|
|
name: build-images-${{ matrix.image_name }}
|
|
runs-on: ubuntu-22.04
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- image_name: api
|
|
target: runtime
|
|
context: elixir
|
|
build-args: |
|
|
APPLICATION_NAME=api
|
|
- image_name: web
|
|
target: runtime
|
|
context: elixir
|
|
build-args: |
|
|
APPLICATION_NAME=web
|
|
- image_name: gateway
|
|
target: debug
|
|
context: rust
|
|
build-args: |
|
|
PACKAGE=firezone-gateway
|
|
- image_name: relay
|
|
target: debug
|
|
context: rust
|
|
build-args: |
|
|
PACKAGE=firezone-relay
|
|
- image_name: client
|
|
target: debug
|
|
context: rust
|
|
build-args: |
|
|
PACKAGE=firezone-linux-client
|
|
- image_name: snownet-tests
|
|
target: debug
|
|
context: rust
|
|
build-args: |
|
|
PACKAGE=snownet-tests
|
|
- image_name: elixir
|
|
target: compiler
|
|
context: elixir
|
|
build-args: |
|
|
APPLICATION_NAME=api
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
env:
|
|
# mark:automatic-version
|
|
VERSION: "1.0.0"
|
|
APPLICATION_NAME: ${{ matrix.image_name }}
|
|
steps:
|
|
- 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.12.0
|
|
- uses: actions/checkout@v4
|
|
- name: Sanitize github.ref_name
|
|
run: |
|
|
# `ref_name` contains `/` which is not a valid docker image tag
|
|
REF="${{ github.ref_name }}"
|
|
CACHE_TAG="${REF//\//-}"
|
|
echo "CACHE_TAG=$CACHE_TAG" >> "$GITHUB_ENV"
|
|
echo "BRANCH_TAG=$CACHE_TAG" >> "$GITHUB_ENV"
|
|
- uses: ./.github/actions/gcp-docker-login
|
|
id: login
|
|
with:
|
|
project: firezone-staging
|
|
- name: Build Docker Tags
|
|
id: build_docker_tags
|
|
run: |
|
|
set -xe
|
|
|
|
TAGS=""
|
|
|
|
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
|
|
MAJOR_VERSION="${VERSION%%.*}"
|
|
MAJOR_MINOR_VERSION="${VERSION%.*}"
|
|
|
|
TAGS="${TAGS},${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${MAJOR_VERSION}"
|
|
TAGS="${TAGS},${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${MAJOR_MINOR_VERSION}"
|
|
TAGS="${TAGS},${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ env.VERSION }}-${{ github.sha }}"
|
|
fi
|
|
|
|
TAGS="${TAGS},${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ env.BRANCH_TAG }}"
|
|
TAGS="${TAGS},${{ steps.login.outputs.registry }}/firezone/${{ matrix.image_name }}:${{ github.sha }}"
|
|
|
|
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
|
|
- name: Build Docker images
|
|
uses: docker/build-push-action@v5
|
|
with:
|
|
platforms: linux/amd64
|
|
build-args: ${{ matrix.build-args }}
|
|
context: ${{ matrix.context }}/
|
|
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
|
|
# This will write the cache on main even if integration tests fail,
|
|
# but it'll just be corrected on the next successful build.
|
|
cache-to: |
|
|
type=registry,ref=${{steps.login.outputs.registry}}/cache/${{ matrix.image_name}}:${{ env.CACHE_TAG }},mode=max
|
|
file: ${{ matrix.context }}/Dockerfile
|
|
push: true
|
|
target: ${{ matrix.target }}
|
|
tags: ${{ steps.build_docker_tags.outputs.tags }}
|
|
|
|
snownet-integration-tests:
|
|
name: snownet-integration-tests-${{ matrix.name }}
|
|
needs: build-images
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
pull-requests: write
|
|
env:
|
|
VERSION: ${{ github.sha }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- file: docker-compose.lan.yml
|
|
name: lan
|
|
- file: docker-compose.wan-hp.yml
|
|
name: wan-hp
|
|
- file: docker-compose.wan-relay.yml
|
|
name: wan-relay
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: ./.github/actions/gcp-docker-login
|
|
id: login
|
|
with:
|
|
project: firezone-staging
|
|
- name: Run ${{ matrix.file }} test
|
|
run: |
|
|
sudo sysctl -w vm.overcommit_memory=1
|
|
timeout 600 docker compose -f rust/snownet-tests/${{ matrix.file }} up --exit-code-from dialer --abort-on-container-exit
|
|
|
|
integration-tests:
|
|
name: integration-tests-${{ matrix.test }}
|
|
needs: build-images
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
pull-requests: write
|
|
env:
|
|
VERSION: ${{ github.sha }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
test: [
|
|
direct-curl-portal-restart,
|
|
relayed-curl-portal-restart,
|
|
relayed-curl-relay-restart,
|
|
direct-curl-portal-down,
|
|
relayed-curl-portal-down,
|
|
direct-curl-portal-relay-down,
|
|
dns-etc-resolvconf,
|
|
dns-nm,
|
|
systemd/dns-systemd-resolved,
|
|
]
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: ./.github/actions/gcp-docker-login
|
|
id: login
|
|
with:
|
|
project: firezone-staging
|
|
- name: Seed database
|
|
run: docker compose run elixir /bin/sh -c 'cd apps/domain && mix ecto.seed'
|
|
- name: Start docker compose in the background
|
|
run: |
|
|
# TODO: Order matters here, but it shouldn't. There seems to be some race
|
|
# condition involved in letting Docker deterime the start order here.
|
|
docker compose up -d dns.httpbin httpbin
|
|
docker compose up -d api web
|
|
docker compose up -d relay
|
|
docker compose up -d gateway
|
|
docker compose up -d client
|
|
|
|
- run: ./scripts/tests/${{ matrix.test }}.sh
|
|
|
|
- name: Show Client logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs client
|
|
- name: Show Relay logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs relay
|
|
- name: Show Gateway logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs gateway
|
|
- name: Show API logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs api
|
|
|
|
perf-tests:
|
|
name: perf-tests-${{ matrix.test_name }}
|
|
needs: build-images
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
pull-requests: write
|
|
env:
|
|
VERSION: ${{ github.sha }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
test_name:
|
|
- direct-tcp-client2server
|
|
- direct-tcp-server2client
|
|
- direct-udp-client2server
|
|
- direct-udp-server2client
|
|
- relayed-tcp-client2server
|
|
- relayed-tcp-server2client
|
|
- relayed-udp-client2server
|
|
- relayed-udp-server2client
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: ./.github/actions/gcp-docker-login
|
|
id: login
|
|
with:
|
|
project: firezone-staging
|
|
- name: Seed database
|
|
run:
|
|
docker compose run elixir /bin/sh -c 'cd apps/domain && mix ecto.seed'
|
|
- name: Start docker compose in the background
|
|
run: |
|
|
# We need to increase the log level to make sure that they don't hold off storm of packets
|
|
# generated by UDP tests. Wire is especially chatty.
|
|
sed -i 's/^\(\s*\)RUST_LOG:.*$/\1RUST_LOG: wire=error,info/' docker-compose.yml
|
|
cat docker-compose.yml | grep RUST_LOG
|
|
|
|
# Start services in the same order each time for the tests
|
|
docker compose up -d iperf3
|
|
docker compose up -d api web
|
|
docker compose up -d relay
|
|
docker compose up -d gateway
|
|
docker compose up -d client
|
|
|
|
- name: 'Performance test: ${{ matrix.test_name }}'
|
|
timeout-minutes: 5
|
|
env:
|
|
TEST_NAME: ${{ matrix.test_name }}
|
|
run: ./scripts/tests/perf/${{ matrix.test_name }}.sh
|
|
- name: 'Save performance test results: ${{ matrix.test_name }}'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
overwrite: true
|
|
name: ${{ matrix.test_name }}-${{ github.ref_name == 'main' && 'main' || github.sha }}-iperf3results
|
|
path: ./${{ matrix.test_name }}.json
|
|
- name: Show Client logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs client
|
|
- name: Show Client UDP stats
|
|
if: "!cancelled()"
|
|
run: docker compose exec client cat /proc/net/udp
|
|
- name: Show Relay logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs relay
|
|
- name: Show Gateway logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs gateway
|
|
- name: Show Gateway UDP stats
|
|
if: "!cancelled()"
|
|
run: docker compose exec gateway cat /proc/net/udp
|
|
- name: Show API logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs api
|
|
- name: Show iperf3 logs
|
|
if: "!cancelled()"
|
|
run: docker compose logs iperf3
|
|
|
|
compare-results:
|
|
if: ${{ github.event_name == 'pull_request' }}
|
|
needs: perf-tests
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
pull-requests: write
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Download PR performance test results
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
pattern: '*-${{ github.sha }}-iperf3results'
|
|
merge-multiple: true
|
|
path: ./
|
|
- name: Get last Continous Delivery workflow run Id
|
|
uses: actions/github-script@v7
|
|
id: get_last_cd_run
|
|
with:
|
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { data } = await github.rest.actions.listWorkflowRuns({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
workflow_id: "cd.yml",
|
|
status: 'success',
|
|
per_page: 1
|
|
});
|
|
return data.workflow_runs[0].id;
|
|
- name: Download main branch performance test results
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
pattern: '*-main-iperf3results'
|
|
merge-multiple: true
|
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
run-id: ${{ steps.get_last_cd_run.outputs.result }}
|
|
path: ./main
|
|
- name: Update PR with results
|
|
uses: actions/github-script@v7
|
|
with:
|
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const { script } = require('./scripts/tests/perf/results.js');
|
|
script(github, context, [
|
|
'direct-tcp-client2server',
|
|
'direct-tcp-server2client',
|
|
'direct-udp-client2server',
|
|
'direct-udp-server2client',
|
|
'relayed-tcp-client2server',
|
|
'relayed-tcp-server2client',
|
|
'relayed-udp-client2server',
|
|
'relayed-udp-server2client'
|
|
]);
|