--- name: CI - Main on: push: branches: - main - next - version-* pull_request: branches: - main - version-* env: POSTGRES_DB: authentik POSTGRES_USER: authentik POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77" permissions: # Needed for checkout contents: read # Needed for codecov OIDC token id-token: write jobs: lint: strategy: fail-fast: false matrix: include: - job: bandit deps: python - job: black deps: python - job: spellcheck deps: node - job: pending-migrations deps: python,runtime - job: ruff deps: python - job: mypy deps: python - job: cargo-deny deps: rust - job: cargo-machete deps: rust - job: clippy deps: rust - job: rustfmt deps: rust-nightly runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 - name: Setup authentik env uses: ./.github/actions/setup with: dependencies: ${{ matrix.deps }} - name: run job run: make ci-lint-${{ matrix.job }} test-gen: runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 with: ref: ${{ github.event.pull_request.head.sha }} - name: Setup authentik env uses: ./.github/actions/setup with: dependencies: "system,python,go,node,runtime,rust-nightly" - name: generate schema run: make migrate gen-build - name: generate API clients run: make gen-clients - name: ensure schema is up-to-date run: git diff --exit-code -- schema.yml blueprints/schema.json packages/client-go packages/client-rust packages/client-ts test-migrations: runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 - name: Setup authentik env uses: ./.github/actions/setup - name: run migrations run: uv run python -m lifecycle.migrate test-make-seed: runs-on: ubuntu-latest steps: - id: seed run: | echo "seed=$(printf "%d\n" "0x$(openssl rand -hex 4)")" >> "$GITHUB_OUTPUT" outputs: seed: ${{ steps.seed.outputs.seed }} test-migrations-from-stable: name: test-migrations-from-stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5 runs-on: ubuntu-latest timeout-minutes: 30 needs: test-make-seed strategy: fail-fast: false matrix: psql: - 14-alpine - 18-alpine run_id: [1, 2, 3, 4, 5] steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 with: fetch-depth: 0 - name: checkout stable run: | set -e -o pipefail cp -R .github .. cp -R scripts .. # Previous stable tag prev_stable=$(git tag --sort=version:refname | grep '^version/' | grep -vE -- '-rc[0-9]+$' | tail -n1) # Current version family based on current_version_family=$(cat internal/constants/VERSION | grep -vE -- 'rc[0-9]+$' || true) if [[ -n $current_version_family ]]; then prev_stable="version/${current_version_family}" fi echo "::notice::Checking out ${prev_stable} as stable version..." git checkout ${prev_stable} rm -rf .github/ scripts/ mv ../.github ../scripts . - name: Setup authentik env (stable) uses: ./.github/actions/setup with: postgresql_version: ${{ matrix.psql }} - name: run migrations to stable run: uv run python -m lifecycle.migrate - name: checkout current code run: | set -x git fetch git reset --hard HEAD git clean -d -fx . git checkout $GITHUB_SHA - name: Setup authentik env (ensure latest deps are installed) uses: ./.github/actions/setup with: postgresql_version: ${{ matrix.psql }} - name: migrate to latest run: | uv run python -m lifecycle.migrate - name: run tests env: # Test in the main database that we just migrated from the previous stable version AUTHENTIK_POSTGRESQL__TEST__NAME: authentik CI_TEST_SEED: ${{ needs.test-make-seed.outputs.seed }} CI_RUN_ID: ${{ matrix.run_id }} CI_TOTAL_RUNS: "5" run: | uv run make ci-test - uses: ./.github/actions/test-results if: ${{ always() }} with: flags: unit-migrate test-unittest: name: test-unittest - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5 runs-on: ubuntu-latest timeout-minutes: 30 needs: test-make-seed strategy: fail-fast: false matrix: psql: - 14-alpine - 18-alpine run_id: [1, 2, 3, 4, 5] steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 - name: Setup authentik env uses: ./.github/actions/setup with: postgresql_version: ${{ matrix.psql }} - name: run unittest env: CI_TEST_SEED: ${{ needs.test-make-seed.outputs.seed }} CI_RUN_ID: ${{ matrix.run_id }} CI_TOTAL_RUNS: "5" run: | uv run make ci-test - uses: ./.github/actions/test-results if: ${{ always() }} with: flags: unit test-integration: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 - name: Setup authentik env uses: ./.github/actions/setup - name: Create k8s Kind Cluster uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 - name: run integration run: | uv run coverage run manage.py test tests/integration uv run coverage combine uv run coverage xml - uses: ./.github/actions/test-results if: ${{ always() }} with: flags: integration test-e2e: name: test-e2e (${{ matrix.job.name }}) runs-on: ubuntu-latest timeout-minutes: 30 strategy: fail-fast: false matrix: job: - name: proxy glob: tests/e2e/test_provider_proxy* profiles: selenium - name: oauth glob: tests/e2e/test_provider_oauth2* tests/e2e/test_source_oauth* profiles: selenium - name: oauth-oidc glob: tests/e2e/test_provider_oidc* profiles: selenium - name: saml glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml* profiles: selenium - name: ldap glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap* - name: rac glob: tests/e2e/test_provider_rac* profiles: selenium - name: ws-fed glob: tests/e2e/test_provider_ws_fed* profiles: selenium - name: radius glob: tests/e2e/test_provider_radius* - name: scim glob: tests/e2e/test_source_scim* - name: flows glob: tests/e2e/test_flows* profiles: selenium - name: endpoints glob: tests/e2e/test_endpoints_* profiles: selenium steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 - name: Setup authentik env uses: ./.github/actions/setup - name: Setup e2e env env: COMPOSE_PROFILES: ${{ matrix.job.profiles }} run: | docker compose -f tests/e2e/compose.yml up -d --quiet-pull - id: cache-web uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v4 if: contains(matrix.job.profiles, 'selenium') with: path: web/dist key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b - name: prepare web ui if: steps.cache-web.outputs.cache-hit != 'true' && contains(matrix.job.profiles, 'selenium') working-directory: web run: | npm ci npm run build npm run build:sfe - name: run e2e run: | uv run coverage run manage.py test ${{ matrix.job.glob }} uv run coverage combine uv run coverage xml - uses: ./.github/actions/test-results if: ${{ always() }} with: flags: e2e test-openid-conformance: name: test-openid-conformance (${{ matrix.job.name }}) runs-on: ubuntu-latest timeout-minutes: 30 strategy: fail-fast: false matrix: job: - name: basic glob: tests/openid_conformance/test_basic.py - name: implicit glob: tests/openid_conformance/test_implicit.py steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 - name: Setup authentik env uses: ./.github/actions/setup - name: Setup e2e env (chrome, etc) env: COMPOSE_PROFILES: selenium run: | docker compose -f tests/e2e/compose.yml up -d --quiet-pull - name: Setup conformance suite run: | docker compose -f tests/openid_conformance/compose.yml up -d --quiet-pull - id: cache-web uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v4 with: path: web/dist key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**', 'web/packages/sfe/src/**') }}-b - name: prepare web ui if: steps.cache-web.outputs.cache-hit != 'true' working-directory: web run: | npm ci npm run build npm run build:sfe - name: run conformance run: | uv run coverage run manage.py test ${{ matrix.job.glob }} uv run coverage combine uv run coverage xml - uses: ./.github/actions/test-results if: ${{ always() }} with: flags: conformance - if: ${{ !cancelled() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: conformance-certification-${{ matrix.job.name }} path: tests/openid_conformance/exports/ test-rust: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 - name: Setup authentik env uses: ./.github/actions/setup with: dependencies: rust,runtime - name: run tests run: | cargo llvm-cov --no-report nextest --workspace cargo llvm-cov report --codecov --output-path target/llvm-cov-target/rust.json - uses: ./.github/actions/test-results if: ${{ always() }} with: files: target/llvm-cov-target/rust.json flags: rust - if: ${{ !cancelled() }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: test-rust path: target/llvm-cov-target/rust.json ci-core-mark: if: always() needs: - lint - test-gen - test-migrations - test-migrations-from-stable - test-unittest - test-integration - test-e2e runs-on: ubuntu-latest steps: - uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1 with: jobs: ${{ toJSON(needs) }} build: permissions: # Needed to upload container images to ghcr.io packages: write # Needed for attestation id-token: write attestations: write # Needed for checkout contents: read needs: ci-core-mark uses: ./.github/workflows/_reusable-docker-build.yml secrets: inherit with: image_name: ${{ github.repository == 'goauthentik/authentik-internal' && 'ghcr.io/goauthentik/internal-server' || 'ghcr.io/goauthentik/dev-server' }} release: false pr-comment: needs: - build runs-on: ubuntu-latest if: ${{ github.event_name == 'pull_request' }} permissions: # Needed to write comments on PRs pull-requests: write timeout-minutes: 120 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 with: ref: ${{ github.event.pull_request.head.sha }} - name: prepare variables uses: ./.github/actions/docker-push-variables id: ev env: DOCKER_USERNAME: ${{ secrets.DOCKER_CORP_USERNAME }} with: image-name: ghcr.io/goauthentik/dev-server - name: Comment on PR if: ${{ steps.ev.outputs.shouldPush == 'true' }} uses: ./.github/actions/comment-pr-instructions with: tag: ${{ steps.ev.outputs.imageMainTag }}