name: Test and publish image on: workflow_dispatch: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read packages: write jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node uses: actions/setup-node@v4 with: node-version: "22" cache: "npm" - name: Install dependencies run: npm ci - name: Type-check / build run: npm run build - name: Run tests run: npm test build: runs-on: ubuntu-latest needs: test steps: - uses: actions/checkout@v4 - name: Build the Docker image run: docker build . --file Dockerfile --tag ghcr.io/${{ github.repository }}:latest --tag ghcr.io/${{ github.repository }}:${{ github.sha }} # Publish only from main: on PRs the image is built as a check but never # pushed — avoids overwriting :latest with unreviewed code and failing on # fork PRs whose GITHUB_TOKEN has no packages:write. - name: Log in to GitHub Container Registry if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Push Docker images if: github.event_name != 'pull_request' run: | docker push ghcr.io/${{ github.repository }}:latest docker push ghcr.io/${{ github.repository }}:${{ github.sha }}