chore(deps): bump all dependencies (closes #40-#48) #219
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: Build and Publish Docker Images | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| reason: | |
| description: 'Reason for manual build' | |
| required: false | |
| default: 'Ad-hoc preview build' | |
| # Cancel in-progress runs for the same branch/PR | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository_owner }}/budgetexperiment | |
| jobs: | |
| build-and-test: | |
| name: Build & Test | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| checks: write | |
| env: | |
| # Dummy connection string for DI validation (tests use in-memory database) | |
| ConnectionStrings__AppDb: "Host=localhost;Database=test;Username=test;Password=test" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Build.props') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Calculate version using MinVer | |
| id: version | |
| run: | | |
| # Install MinVer CLI tool | |
| dotnet tool install --global minver-cli | |
| # Calculate version (uses git tags) | |
| VERSION=$(minver --tag-prefix v --default-pre-release-identifiers preview) | |
| echo "Calculated version: $VERSION" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Restore dependencies | |
| run: dotnet restore BudgetExperiment.sln | |
| - name: Build solution | |
| run: dotnet build BudgetExperiment.sln --configuration Release --no-restore | |
| - name: Run tests with coverage | |
| run: | | |
| dotnet test BudgetExperiment.sln \ | |
| --configuration Release \ | |
| --no-build \ | |
| --filter "FullyQualifiedName!~E2E&Category!=ExternalDependency" \ | |
| --collect:"XPlat Code Coverage" \ | |
| --logger "trx" \ | |
| --results-directory ./TestResults | |
| - name: Merge coverage reports | |
| uses: danielpalme/ReportGenerator-GitHub-Action@5 | |
| with: | |
| reports: ./TestResults/**/coverage.cobertura.xml | |
| targetdir: ./CoverageReport | |
| reporttypes: Cobertura;MarkdownSummaryGithub | |
| - name: Publish coverage summary | |
| if: always() | |
| run: cat ./CoverageReport/SummaryGithub.md >> $GITHUB_STEP_SUMMARY | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: test-results | |
| path: ./TestResults/*.trx | |
| retention-days: 7 | |
| - name: Test Summary | |
| uses: dorny/test-reporter@v2 | |
| if: always() | |
| with: | |
| name: Test Results | |
| path: ./TestResults/*.trx | |
| reporter: dotnet-trx | |
| # Publish application (framework-dependent, works on all architectures) | |
| - name: Publish application | |
| run: | | |
| dotnet publish src/BudgetExperiment.Api/BudgetExperiment.Api.csproj \ | |
| --configuration Release \ | |
| --no-build \ | |
| --output ./publish \ | |
| /p:UseAppHost=false \ | |
| /p:MinVerVersionOverride=${{ steps.version.outputs.version }} | |
| - name: Upload publish artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: app-publish | |
| path: ./publish | |
| retention-days: 1 | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| # Matrix build for each architecture (parallel, native runners) | |
| docker-build: | |
| name: Docker Build (${{ matrix.platform }}) | |
| runs-on: ${{ matrix.runner }} | |
| needs: build-and-test | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: linux/amd64 | |
| suffix: amd64 | |
| runner: ubuntu-latest | |
| - platform: linux/arm64 | |
| suffix: arm64 | |
| runner: ubuntu-24.04-arm | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Download publish artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: app-publish | |
| path: ./publish | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| # Build and push single-platform image | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: ./Dockerfile.prebuilt | |
| platforms: ${{ matrix.platform }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha,scope=${{ matrix.platform }} | |
| cache-to: type=gha,mode=max,scope=${{ matrix.platform }} | |
| outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true | |
| - name: Export digest | |
| run: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: digests-${{ matrix.suffix }} | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| # Merge platform-specific images into multi-arch manifest | |
| docker-merge: | |
| name: Create Multi-Arch Manifest | |
| runs-on: ubuntu-latest | |
| needs: docker-build | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: /tmp/digests | |
| pattern: digests-* | |
| merge-multiple: true | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=sha,prefix= | |
| type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} | |
| type=raw,value=preview,enable=${{ github.event_name == 'workflow_dispatch' }} | |
| - name: Create manifest list and push | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) | |
| - name: Inspect image | |
| run: | | |
| docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} |