Release #201
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: Release | |
| on: | |
| # Nightly builds after CI passes on main | |
| workflow_run: | |
| workflows: ["CI"] | |
| types: | |
| - completed | |
| branches: | |
| - main | |
| - develop | |
| # Stable releases on version tags | |
| push: | |
| tags: | |
| - 'v*' | |
| # Manual trigger | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| env: | |
| DOTNET_VERSION: '10.0.x' | |
| NODE_VERSION: '22.x' | |
| MAJOR_VERSION: '0.0.1' | |
| NUGET_CERT_REVOCATION_MODE: offline | |
| DOTNET_CLI_TELEMETRY_OPTOUT: 1 | |
| DOTNET_NOLOGO: true | |
| DOTNET_MULTILEVEL_LOOKUP: 0 | |
| jobs: | |
| frontend: | |
| name: Build Frontend | |
| # Only run if CI passed (workflow_run), or if triggered by tag/manual | |
| if: > | |
| github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'yarn' | |
| - name: Install frontend dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Build frontend | |
| run: yarn build --env production | |
| - name: Upload frontend build | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: release-frontend | |
| path: _output/UI | |
| retention-days: 1 | |
| build: | |
| name: Build (${{ matrix.runtime }}) | |
| needs: frontend | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - runtime: win-x64 | |
| os: windows-latest | |
| - runtime: win-x86 | |
| os: windows-latest | |
| - runtime: linux-x64 | |
| os: ubuntu-latest | |
| - runtime: linux-arm64 | |
| os: ubuntu-latest | |
| - runtime: linux-arm | |
| os: ubuntu-latest | |
| - runtime: linux-musl-x64 | |
| os: ubuntu-latest | |
| - runtime: linux-musl-arm64 | |
| os: ubuntu-latest | |
| - runtime: osx-x64 | |
| os: macos-latest | |
| - runtime: osx-arm64 | |
| os: macos-latest | |
| # freebsd-x64 disabled: .NET 8.0.25 runtime not yet available in dotnet-bsd-crossbuild feed (latest: 8.0.12) | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Compute NuGet cache key | |
| id: nuget-key | |
| shell: bash | |
| run: echo "hash=$(find src -name '*.csproj' | sort | xargs cat | tr -d '\r' | shasum -a 256 | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" | |
| - name: NuGet cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.nuget/packages | |
| key: nuget-${{ steps.nuget-key.outputs.hash }} | |
| restore-keys: nuget- | |
| enableCrossOsArchive: true | |
| - name: Calculate version | |
| id: version | |
| shell: bash | |
| run: | | |
| if [[ "${{ github.ref }}" == refs/tags/v* ]]; then | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| else | |
| VERSION="${{ env.MAJOR_VERSION }}.${{ github.run_number }}" | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Version: $VERSION" | |
| - name: Update version in project | |
| shell: bash | |
| run: | | |
| sed -i.bak "s/<AssemblyVersion>[0-9.*]\+<\/AssemblyVersion>/<AssemblyVersion>${{ steps.version.outputs.version }}<\/AssemblyVersion>/g" src/Directory.Build.props | |
| - name: Build backend | |
| shell: bash | |
| run: | | |
| dotnet msbuild -restore src/Gamarr.sln \ | |
| -p:Configuration=Release \ | |
| -p:Platform=Posix \ | |
| -p:RuntimeIdentifiers=${{ matrix.runtime }} \ | |
| -t:PublishAllRids | |
| - name: Download frontend build | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: release-frontend | |
| path: _output/UI | |
| - name: Package | |
| shell: bash | |
| run: | | |
| runtime="${{ matrix.runtime }}" | |
| version="${{ steps.version.outputs.version }}" | |
| mkdir -p _artifacts/$runtime | |
| cp -r _output/net8.0/$runtime/publish/* _artifacts/$runtime/ | |
| cp -r _output/UI _artifacts/$runtime/ | |
| cp LICENSE _artifacts/$runtime/ | |
| # Remove platform-specific files | |
| if [[ "$runtime" == win-* ]]; then | |
| rm -f _artifacts/$runtime/Gamarr.Mono.* 2>/dev/null || true | |
| else | |
| rm -f _artifacts/$runtime/Gamarr.Windows.* 2>/dev/null || true | |
| fi | |
| - name: Create archive (Unix) | |
| if: ${{ !startsWith(matrix.runtime, 'win-') }} | |
| shell: bash | |
| run: | | |
| cd _artifacts | |
| tar -czvf Gamarr.${{ steps.version.outputs.version }}.${{ matrix.runtime }}.tar.gz ${{ matrix.runtime }} | |
| - name: Create archive (Windows) | |
| if: ${{ startsWith(matrix.runtime, 'win-') }} | |
| shell: bash | |
| run: | | |
| cd _artifacts | |
| 7z a -tzip Gamarr.${{ steps.version.outputs.version }}.${{ matrix.runtime }}.zip ${{ matrix.runtime }} | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: Gamarr-${{ matrix.runtime }} | |
| path: _artifacts/Gamarr.${{ steps.version.outputs.version }}.${{ matrix.runtime }}.* | |
| retention-days: 30 | |
| release: | |
| name: Create Release | |
| runs-on: ubuntu-latest | |
| needs: build | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| - name: Calculate version | |
| id: version | |
| run: | | |
| # Handle both direct push and workflow_run triggers | |
| if [[ "${{ github.event_name }}" == "workflow_run" ]]; then | |
| BRANCH="${{ github.event.workflow_run.head_branch }}" | |
| else | |
| BRANCH="${{ github.ref }}" | |
| fi | |
| if [[ "$BRANCH" == refs/tags/v* || "$BRANCH" == v* ]]; then | |
| VERSION="${BRANCH#refs/tags/}" | |
| VERSION="${VERSION#v}" | |
| PRERELEASE="false" | |
| CHANNEL="stable" | |
| elif [[ "$BRANCH" == *"develop"* ]]; then | |
| VERSION="${{ env.MAJOR_VERSION }}.${{ github.run_number }}" | |
| PRERELEASE="true" | |
| CHANNEL="develop" | |
| else | |
| VERSION="${{ env.MAJOR_VERSION }}.${{ github.run_number }}" | |
| PRERELEASE="true" | |
| CHANNEL="nightly" | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "prerelease=$PRERELEASE" >> $GITHUB_OUTPUT | |
| echo "channel=$CHANNEL" >> $GITHUB_OUTPUT | |
| echo "Version: $VERSION, Prerelease: $PRERELEASE, Channel: $CHANNEL" | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: artifacts | |
| pattern: Gamarr-* | |
| merge-multiple: true | |
| - name: List artifacts | |
| run: find artifacts -type f | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: v${{ steps.version.outputs.version }} | |
| name: ${{ steps.version.outputs.version }} | |
| prerelease: ${{ steps.version.outputs.prerelease }} | |
| generate_release_notes: true | |
| files: | | |
| artifacts/**/*.tar.gz | |
| artifacts/**/*.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| docker: | |
| name: Build Docker Images | |
| runs-on: ubuntu-latest | |
| needs: release | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| - name: Calculate version | |
| id: version | |
| run: | | |
| # Handle both direct push and workflow_run triggers | |
| if [[ "${{ github.event_name }}" == "workflow_run" ]]; then | |
| BRANCH="${{ github.event.workflow_run.head_branch }}" | |
| else | |
| BRANCH="${{ github.ref }}" | |
| fi | |
| if [[ "$BRANCH" == refs/tags/v* || "$BRANCH" == v* ]]; then | |
| VERSION="${BRANCH#refs/tags/}" | |
| VERSION="${VERSION#v}" | |
| CHANNEL="stable" | |
| elif [[ "$BRANCH" == *"develop"* ]]; then | |
| VERSION="${{ env.MAJOR_VERSION }}.${{ github.run_number }}" | |
| CHANNEL="develop" | |
| else | |
| VERSION="${{ env.MAJOR_VERSION }}.${{ github.run_number }}" | |
| CHANNEL="nightly" | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "channel=$CHANNEL" >> $GITHUB_OUTPUT | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: ghcr.io/${{ github.repository }} | |
| tags: | | |
| type=raw,value=${{ steps.version.outputs.version }} | |
| type=raw,value=latest,enable=${{ steps.version.outputs.channel == 'stable' }} | |
| type=raw,value=develop,enable=${{ steps.version.outputs.channel == 'develop' }} | |
| type=raw,value=nightly,enable=${{ steps.version.outputs.channel == 'nightly' }} | |
| - name: Build and push | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| build-args: | | |
| BUILD_DATE=${{ github.event.repository.updated_at }} | |
| VERSION=${{ steps.version.outputs.version }} | |
| GAMARR_RELEASE=${{ steps.version.outputs.version }} |