Files
firezone/.github/workflows/test.yml
Andrew Dryga af431c0a6f Rework configurations (#1352)
- [x] All configs should support ENV variable overrides over DB values
- [ ] ~Adding a new field to DB value should automatically write ENV
config to DB on app boot (so that we don't need migrations)~
- [x] Validate configs and report human-readable errors when something
is wrong, telling where it's invalid (eg. env key X) and what's wrong
with it
- [x] Reuse Changeset validations (we still have a DB schema and UI
form, and want to make sure it's valid)
- [x] Auto-generate docs
- [x] Merge `Config` and `Configurations` into one `Config` context
- [x] Lock out UI fields for configurations when there is an ENV
override
- [x] Lock out corresponding REST API configuration field if overridden
via ENV var
- [x] Log a warning when deprecated legacy var is used
- [x] Document precedence: ENV -> Legacy ENV -> File -> DB
- [x] Change type to `inet[]` for `configurations.{default_client_dns,
default_client_allowed_ips}`, `devices.{dns, allowed_ips}`,
- [x] Drop `EctoNetwork` dep
- [x] `s/phoenix_port/phoenix_http_port` because it doesn't configure
HTTPS server
- [x] Do not load DB configs when config can be resolved from other
sources

Maybe:
- [ ] ~Auto-generate Ecto types to automatically cast/dump values
to/from DB~
- [ ] Allow JSON file config source
- [x] DB-related configs will not be validated?

Closes #1162
Closes #1313
Closes #1374
Closes #1432
2023-02-21 10:38:53 -06:00

395 lines
13 KiB
YAML

name: Test
on:
pull_request:
push:
branches:
- master
jobs:
unit-test:
runs-on: ubuntu-latest
env:
MIX_ENV: test
POSTGRES_HOST: localhost
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
services:
postgres:
image: postgres:15
ports:
- 5432:5432
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Install package dependencies
run: |
sudo apt-get install -q -y \
net-tools \
wireguard
- uses: actions/checkout@v3
- uses: erlef/setup-beam@v1
with:
otp-version: '25'
elixir-version: '1.14'
- uses: actions/cache@v3
name: Elixir Deps Cache
env:
cache-name: cache-elixir-deps-${{ env.MIX_ENV }}
with:
path: deps
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-
- uses: actions/cache@v3
name: Elixir Build Cache
env:
cache-name: cache-elixir-build-${{ env.MIX_ENV }}
with:
path: _build
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
- name: Install Dependencies
run: mix deps.get --only $MIX_ENV
- name: Compile Dependencies
run: mix deps.compile --skip-umbrella-children
- name: Compile Application
run: mix compile
- name: Setup Database
run: |
mix ecto.create
mix ecto.migrate
- name: Run Tests and Upload Coverage Report
env:
E2E_MAX_WAIT_SECONDS: 20
run: |
# XXX: This can fail when coveralls is down
mix coveralls.github --umbrella --warnings-as-errors
- name: Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Elixir Unit Test Report
path: _build/test/lib/*/test-junit-report.xml
reporter: java-junit
type-check:
runs-on: ubuntu-latest
env:
MIX_ENV: dev
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
- uses: erlef/setup-beam@v1
with:
otp-version: '25'
elixir-version: '1.14'
- uses: actions/cache@v3
name: Elixir Deps Cache
env:
cache-name: cache-elixir-deps-${{ env.MIX_ENV }}
with:
path: deps
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-
- uses: actions/cache@v3
name: Elixir Build Cache
env:
cache-name: cache-elixir-build-${{ env.MIX_ENV }}
with:
path: _build
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
- name: Install Dependencies
run: mix deps.get --only $MIX_ENV
- name: Compile Dependencies
run: mix deps.compile --skip-umbrella-children
- name: Compile Application
run: mix compile
# Don't cache PLTs based on mix.lock hash, as Dialyzer can incrementally update even old ones
# Cache key based on Elixir & Erlang version (also useful when running in matrix)
- name: Restore PLT cache
uses: actions/cache@v3
env:
cache-name: cache-erlang-plt-${{ env.MIX_ENV }}
with:
key: ${{ runner.os }}-${{ steps.setup-beam.outputs.elixir-version }}-${{ steps.setup-beam.outputs.otp-version }}-plt
restore-keys: |
${{ runner.os }}-${{ steps.setup-beam.outputs.elixir-version }}-${{ steps.setup-beam.outputs.otp-version }}-plt
path: priv/plts
- name: Create PLTs
if: steps.plt_cache.outputs.cache-hit != 'true'
run: mix dialyzer --plt
- name: Run Dialyzer
run: mix dialyzer --format dialyxir
static-analysis:
runs-on: ubuntu-latest
env:
MIX_ENV: test
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
- uses: erlef/setup-beam@v1
with:
otp-version: '25'
elixir-version: '1.14'
- uses: actions/cache@v3
name: Elixir Deps Cache
env:
cache-name: cache-elixir-deps-${{ env.MIX_ENV }}
with:
path: deps
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-
- uses: actions/cache@v3
name: Elixir Build Cache
env:
cache-name: cache-elixir-build-${{ env.MIX_ENV }}
with:
path: _build
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
- name: Install Dependencies
run: mix deps.get --only $MIX_ENV
- name: Compile Dependencies
run: mix deps.compile --skip-umbrella-children
- name: Compile Application
run: mix compile --force --warnings-as-errors
- name: Check Formatting
run: mix format --check-formatted
- name: Run Credo
run: mix credo --strict
migrations-and-seed-test:
runs-on: ubuntu-latest
env:
MIX_ENV: dev
POSTGRES_HOST: localhost
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FZ_VPN_WG_ADAPTER: FzVpn.Interface.WGAdapter.Sandbox
services:
postgres:
image: postgres:15
ports:
- 5432:5432
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Install package dependencies
run: |
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/trusted.gpg.d/pgdg.asc &>/dev/null
sudo apt update
sudo apt-get install -q -y \
net-tools \
wireguard \
postgresql-client
- uses: actions/checkout@v3
- uses: erlef/setup-beam@v1
with:
otp-version: '25'
elixir-version: '1.14'
- uses: actions/cache@v3
name: Elixir Deps Cache
env:
cache-name: cache-elixir-deps-${{ env.MIX_ENV }}-${{ env.MIX_ENV }}
with:
path: deps
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-
- uses: actions/cache@v3
name: Elixir Build Cache
env:
cache-name: cache-elixir-build-${{ env.MIX_ENV }}
with:
path: _build
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
- name: Install Dependencies
run: mix deps.get --only $MIX_ENV
- name: Compile
run: mix compile
- name: Download master branch DB dump
id: download-artifact
uses: dawidd6/action-download-artifact@v2
if: "!contains(github.ref, 'master')"
with:
branch: master
name: db-dump
path: apps/fz_http/priv/repo/
search_artifacts: true
workflow_conclusion: completed
if_no_artifact_found: fail
- name: Create Database
run: |
mix ecto.create
- name: Restore DB dump
if: "!contains(github.ref, 'master')"
env:
PGPASSWORD: postgres
run: |
mix ecto.load
- name: Run new migrations
run: |
mix ecto.migrate
- name: Dump DB
if: "contains(github.ref, 'master')"
env:
PGPASSWORD: postgres
run: |
pg_dump firezone_dev \
-U postgres -h localhost \
--file apps/fz_http/priv/repo/structure.sql \
--no-acl \
--no-owner
- name: Upload master branch DB dump
if: "contains(github.ref, 'master')"
uses: actions/upload-artifact@v3
with:
name: db-dump
path: apps/fz_http/priv/repo/structure.sql
- name: Run Seed
run: mix ecto.seed
acceptance-test:
runs-on: ubuntu-latest
env:
MIX_ENV: test
POSTGRES_HOST: localhost
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MIX_TEST_PARTITIONS: 4
strategy:
fail-fast: false
matrix:
MIX_TEST_PARTITION: [1, 2, 3, 4]
services:
postgres:
image: postgres:15
ports:
- 5432:5432
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
vault:
image: vault:1.12.2
env:
VAULT_ADDR: 'http://127.0.0.1:8200'
VAULT_DEV_ROOT_TOKEN_ID: 'firezone'
ports:
- 8200:8200/tcp
options:
--cap-add=IPC_LOCK
saml-idp:
image: vihangk1/docker-test-saml-idp:latest
env:
SIMPLESAMLPHP_SP_ENTITY_ID: 'urn:firezone.dev:firezone-app'
SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE: 'http://localhost:13000/auth/saml/sp/consume/mysamlidp'
SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE: 'http://localhost:13000/auth/saml/sp/logout/mysamlidp'
SIMPLESAMLPHP_SP_NAME_ID_FORMAT: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'
SIMPLESAMLPHP_SP_NAME_ID_ATTRIBUTE: 'email'
SIMPLESAMLPHP_IDP_AUTH: 'example-userpass'
ports:
- 8400:8080/tcp
- 8443:8443/tcp
steps:
- uses: nanasess/setup-chromedriver@v1
- run: |
export DISPLAY=:99
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
- name: Install package dependencies
run: |
sudo apt-get install -q -y \
net-tools \
wireguard
- uses: actions/checkout@v3
- uses: erlef/setup-beam@v1
with:
otp-version: '25'
elixir-version: '1.14'
- uses: actions/cache@v3
name: Elixir Deps Cache
env:
cache-name: cache-elixir-deps-${{ env.MIX_ENV }}-${{ env.MIX_ENV }}
with:
path: deps
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-
- uses: actions/cache@v3
name: Elixir Build Cache
env:
cache-name: cache-elixir-build-${{ env.MIX_ENV }}
with:
path: _build
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
- uses: actions/cache@v3
name: Yarn Deps Cache
env:
cache-name: cache-yarn-build-${{ env.MIX_ENV }}
with:
path: apps/fz_http/assets/node_modules
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
- uses: actions/cache@v3
name: Assets Cache
env:
cache-name: cache-assets-build-${{ env.MIX_ENV }}
with:
path: apps/fz_http/priv/static/dist
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
- name: Install Dependencies
run: mix deps.get --only $MIX_ENV
- name: Compile Dependencies
run: mix deps.compile --skip-umbrella-children
- name: Compile Application
run: mix compile
- name: Install Node Dependencies
run: |
cd apps/fz_http/assets
yarn install --frozen-lockfile
- name: Build Assets
run: |
cd apps/fz_http/assets
yarn deploy
- name: Setup Database
run: |
mix ecto.create
mix ecto.migrate
- name: Run Acceptance Tests
env:
MIX_TEST_PARTITION: ${{ matrix.MIX_TEST_PARTITION }}
E2E_MAX_WAIT_SECONDS: 5
run: |
mix test --only acceptance:true \
--partitions=${{ env.MIX_TEST_PARTITIONS }} \
--no-compile \
--no-archives-check \
--no-deps-check \
|| pkill -f chromedriver \
|| mix test --only acceptance:true --failed \
|| pkill -f chromedriver \
|| mix test --only acceptance:true --failed
- name: Save Screenshots
if: always()
uses: actions/upload-artifact@v3
with:
name: screenshots
path: apps/fz_http/screenshots
- name: Test Report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Elixir Acceptance Test Report
path: _build/test/lib/*/test-junit-report.xml
reporter: java-junit