test: add end-to-end testing infrastructure #40
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Continuous Delivery | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check-out repository | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install mise | |
| uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3 | |
| - name: Run CI | |
| run: mise run ci:check | |
| test: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] | |
| steps: | |
| - name: Check-out repository | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install mise | |
| uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3 | |
| with: | |
| # Workaround: Use `--env ci` to load mise.ci.toml which contains constant tools (uv). | |
| # This allows us to override only the Python version via install-args without duplicating | |
| # tool definitions. | |
| install-args: "python@${{ matrix.python-version }} --env ci" | |
| - name: Run unit tests | |
| run: mise run ci:test:unit | |
| e2e-tests: | |
| runs-on: ubuntu-latest | |
| if: (github.ref == 'refs/heads/main' && github.event_name == 'push') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-e2e')) | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Check-out repository | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install mise | |
| uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3 | |
| - name: Read Immich version | |
| id: immich-version | |
| run: echo "version=$(cat IMMICH-VERSION | tr -d '[:space:]')" >> $GITHUB_OUTPUT | |
| - name: Clone Immich repository | |
| run: | | |
| git clone --depth 1 --branch $IMMICH_VERSION https://github.com/immich-app/immich.git immich-git-repo | |
| env: | |
| IMMICH_VERSION: ${{ steps.immich-version.outputs.version }} | |
| - name: Login to GitHub Container Registry | |
| run: | | |
| echo "${{ github.token }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin | |
| - name: Start Immich server | |
| working-directory: ./immich-git-repo/e2e | |
| run: | | |
| docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans | |
| echo "Waiting for Immich e2e environment to be ready..." | |
| timeout 60s bash -lc 'until docker logs immich-e2e-server 2>&1 | grep -q "Immich Microservices is running"; do sleep 1; done' | |
| echo "Immich e2e environment is ready!" | |
| # Note: This startup process is identical to the one in Immich's e2e setup. | |
| # We are depending on the same log message to be printed. For reference, see: | |
| # - server/src/workers/microservices.ts | |
| # - e2e/src/setup/docker-compose.ts | |
| - name: Run e2e tests | |
| env: | |
| IMMICH_URL: http://127.0.0.1:2285 | |
| IMMICH_API_URL: http://127.0.0.1:2285/api | |
| run: mise run ci:test:e2e | |
| - name: Show docker logs on failure | |
| if: failure() | |
| working-directory: ./immich-git-repo/e2e | |
| run: docker compose logs | |
| - name: Teardown Immich server | |
| if: always() | |
| working-directory: ./immich-git-repo/e2e | |
| run: docker compose down | |
| release: | |
| runs-on: ubuntu-latest | |
| needs: [lint, test, e2e-tests] | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| concurrency: | |
| group: ${{ github.workflow }}-release-${{ github.ref_name }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Setup | Checkout Repository on Release Branch | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.RELEASE_PAT }} | |
| persist-credentials: false | |
| - name: Setup | Force release branch to be at workflow sha | |
| run: | | |
| git reset --hard ${TRIGGER_SHA} | |
| env: | |
| TRIGGER_SHA: ${{ github.sha }} | |
| - name: Action | Semantic Version Release | |
| id: release | |
| uses: python-semantic-release/python-semantic-release@350c48fcb3ffcdfd2e0a235206bc2ecea6b69df0 # v10 | |
| with: | |
| directory: ./ | |
| github_token: ${{ secrets.RELEASE_PAT }} | |
| git_committer_name: "github-actions" | |
| git_committer_email: "actions@users.noreply.github.com" | |
| changelog: false # github releases are sufficient | |
| - name: Upload | Distribution Artifacts | |
| if: steps.release.outputs.released == 'true' | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | |
| with: | |
| name: distribution-artifacts | |
| path: dist | |
| if-no-files-found: error | |
| outputs: | |
| released: ${{ steps.release.outputs.released || 'false' }} | |
| deploy: | |
| runs-on: ubuntu-latest | |
| needs: release | |
| if: ${{ needs.release.outputs.released == 'true' }} | |
| permissions: | |
| id-token: write | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/immich | |
| steps: | |
| - name: Setup | Download Build Artifacts | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 | |
| id: artifact-download | |
| with: | |
| name: distribution-artifacts | |
| path: dist | |
| - name: Publish | Upload package to PyPI | |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 | |
| with: | |
| packages-dir: dist/ |