warmup #128
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 Pipeline | |
| on: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pages: write | |
| id-token: write | |
| concurrency: | |
| group: release-pipeline | |
| cancel-in-progress: true | |
| env: | |
| APP_TEST_PROJECT: tests/PrompterOne.Web.Tests/PrompterOne.Web.Tests.csproj | |
| CORE_TEST_PROJECT: tests/PrompterOne.Core.Tests/PrompterOne.Core.Tests.csproj | |
| PLAYWRIGHT_CLI: tests/PrompterOne.Web.UITests/bin/Debug/net10.0/.playwright/package/cli.js | |
| SOLUTION_FILE: PrompterOne.slnx | |
| jobs: | |
| build_supporting_suites: | |
| name: Restore + Build Supporting Suites | |
| runs-on: macos-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Restore solution | |
| run: dotnet restore "$SOLUTION_FILE" | |
| - name: Restore WebAssembly workload | |
| run: dotnet workload restore | |
| - name: Build solution | |
| run: dotnet build "$SOLUTION_FILE" -warnaserror | |
| test_supporting_suites: | |
| name: Run Supporting Suites | |
| needs: build_supporting_suites | |
| runs-on: macos-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Expose GitHub Actions Runtime | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env['ACTIONS_RUNTIME_TOKEN']); | |
| core.exportVariable('ACTIONS_RESULTS_URL', process.env['ACTIONS_RESULTS_URL']); | |
| - name: Test supporting suites | |
| run: | | |
| dotnet test --project "$CORE_TEST_PROJECT" | |
| dotnet test --project "$APP_TEST_PROJECT" | |
| build_browser_suites: | |
| name: Restore + Build Browser Suites | |
| runs-on: macos-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Restore solution | |
| run: dotnet restore "$SOLUTION_FILE" | |
| - name: Restore WebAssembly workload | |
| run: dotnet workload restore | |
| - name: Build solution | |
| run: dotnet build "$SOLUTION_FILE" -warnaserror | |
| test_browser_suites: | |
| name: Run Browser Suite (${{ matrix.suite.name }}) | |
| needs: build_browser_suites | |
| runs-on: macos-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| suite: | |
| - name: Shell | |
| artifact: shell | |
| project: tests/PrompterOne.Web.UITests.Shell/PrompterOne.Web.UITests.Shell.csproj | |
| - name: Studio | |
| artifact: studio | |
| project: tests/PrompterOne.Web.UITests.Studio/PrompterOne.Web.UITests.Studio.csproj | |
| - name: Editor | |
| artifact: editor | |
| project: tests/PrompterOne.Web.UITests.Editor/PrompterOne.Web.UITests.Editor.csproj | |
| - name: Reader | |
| artifact: reader | |
| project: tests/PrompterOne.Web.UITests.Reader/PrompterOne.Web.UITests.Reader.csproj | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Expose GitHub Actions Runtime | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env['ACTIONS_RUNTIME_TOKEN']); | |
| core.exportVariable('ACTIONS_RESULTS_URL', process.env['ACTIONS_RESULTS_URL']); | |
| - name: Restore solution | |
| run: dotnet restore "$SOLUTION_FILE" | |
| - name: Restore WebAssembly workload | |
| run: dotnet workload restore | |
| - name: Build solution | |
| run: dotnet build "$SOLUTION_FILE" -warnaserror | |
| - name: Install Playwright browser | |
| run: node "$PLAYWRIGHT_CLI" install chromium | |
| - name: Test browser suite | |
| run: dotnet test --project "${{ matrix.suite.project }}" | |
| - name: Upload Playwright artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: playwright-artifacts-release-pipeline-${{ matrix.suite.artifact }} | |
| path: output/playwright/ | |
| if-no-files-found: ignore | |
| prepare_release: | |
| name: Resolve Release Version | |
| needs: | |
| - test_supporting_suites | |
| - test_browser_suites | |
| runs-on: macos-latest | |
| env: | |
| APP_PROJECT: src/PrompterOne.Web/PrompterOne.Web.csproj | |
| permissions: | |
| contents: read | |
| outputs: | |
| release_tag: ${{ steps.release_version.outputs.release_tag }} | |
| release_version: ${{ steps.release_version.outputs.release_version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Restore WebAssembly workload | |
| run: dotnet workload restore | |
| - name: Resolve release version | |
| id: release_version | |
| run: | | |
| release_version="$(dotnet msbuild "$APP_PROJECT" -getProperty:VersionPrefix -p:PrompterOneBuildNumber=${{ github.run_number }} | tr -d '\r')" | |
| release_tag="v${release_version}" | |
| echo "release_version=$release_version" >> "$GITHUB_OUTPUT" | |
| echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT" | |
| publish_release_build: | |
| name: Publish Release Build | |
| needs: prepare_release | |
| runs-on: macos-latest | |
| env: | |
| APP_PROJECT: src/PrompterOne.Web/PrompterOne.Web.csproj | |
| PAGES_ARTIFACT_ROOT: .artifacts/prompterone-pages | |
| PAGES_BASE_PATH: / | |
| PAGES_CNAME: app.prompter.one | |
| PUBLISH_ROOT: .artifacts/prompterone-publish | |
| RELEASE_ARCHIVE_NAME: prompterone-pages.zip | |
| RELEASE_ARTIFACT_NAME: prompterone-release-package | |
| RELEASE_ARTIFACT_ROOT: .artifacts/release-artifact | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| global-json-file: global.json | |
| - name: Restore WebAssembly workload | |
| run: dotnet workload restore | |
| - name: Publish standalone WASM app | |
| run: > | |
| dotnet publish | |
| "$APP_PROJECT" | |
| -c Release | |
| -o "$PUBLISH_ROOT" | |
| -p:PrompterOneBuildNumber=${{ github.run_number }} | |
| - name: Prepare GitHub Pages artifact | |
| run: | | |
| mkdir -p "$PAGES_ARTIFACT_ROOT" | |
| cp -R "$PUBLISH_ROOT/wwwroot/." "$PAGES_ARTIFACT_ROOT/" | |
| pages_index_path="$PAGES_ARTIFACT_ROOT/index.html" | |
| pages_index_temp_path="$PAGES_ARTIFACT_ROOT/index.html.tmp" | |
| sed "s#<base href=\"/\" />#<base href=\"${PAGES_BASE_PATH}\" />#g" "$pages_index_path" > "$pages_index_temp_path" | |
| mv "$pages_index_temp_path" "$pages_index_path" | |
| cp "$PAGES_ARTIFACT_ROOT/index.html" "$PAGES_ARTIFACT_ROOT/404.html" | |
| printf '%s\n' "$PAGES_CNAME" > "$PAGES_ARTIFACT_ROOT/CNAME" | |
| touch "$PAGES_ARTIFACT_ROOT/.nojekyll" | |
| - name: Archive release bundle | |
| run: | | |
| mkdir -p "$RELEASE_ARTIFACT_ROOT" | |
| cd "$PAGES_ARTIFACT_ROOT" | |
| zip -r "$GITHUB_WORKSPACE/$RELEASE_ARTIFACT_ROOT/$RELEASE_ARCHIVE_NAME" . | |
| - name: Upload GitHub release artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ env.RELEASE_ARTIFACT_NAME }} | |
| path: ${{ env.RELEASE_ARTIFACT_ROOT }}/${{ env.RELEASE_ARCHIVE_NAME }} | |
| - name: Upload Pages artifact | |
| uses: actions/upload-pages-artifact@v4 | |
| with: | |
| path: ${{ env.PAGES_ARTIFACT_ROOT }} | |
| publish_github_release: | |
| name: Publish GitHub Release | |
| needs: | |
| - prepare_release | |
| - publish_release_build | |
| runs-on: macos-latest | |
| env: | |
| RELEASE_ARCHIVE_NAME: prompterone-pages.zip | |
| RELEASE_ARTIFACT_NAME: prompterone-release-package | |
| RELEASE_ARTIFACT_ROOT: .artifacts/release-artifact | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Download release artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ env.RELEASE_ARTIFACT_NAME }} | |
| path: ${{ env.RELEASE_ARTIFACT_ROOT }} | |
| - name: Resolve release asset path | |
| id: release_asset | |
| run: | | |
| release_asset="$(find "$RELEASE_ARTIFACT_ROOT" -type f -name "$RELEASE_ARCHIVE_NAME" | head -n 1)" | |
| if [ -z "$release_asset" ]; then | |
| echo "Expected release archive '$RELEASE_ARCHIVE_NAME' was not found under '$RELEASE_ARTIFACT_ROOT'." >&2 | |
| exit 1 | |
| fi | |
| echo "release_asset=$release_asset" >> "$GITHUB_OUTPUT" | |
| - name: Create or update release tag and GitHub Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GH_REPO: ${{ github.repository }} | |
| RELEASE_TAG: ${{ needs.prepare_release.outputs.release_tag }} | |
| RELEASE_TITLE: PrompterOne ${{ needs.prepare_release.outputs.release_version }} | |
| run: | | |
| release_asset="${{ steps.release_asset.outputs.release_asset }}" | |
| if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then | |
| gh release upload "$RELEASE_TAG" "$release_asset" --clobber | |
| gh release edit "$RELEASE_TAG" --title "$RELEASE_TITLE" | |
| else | |
| gh release create "$RELEASE_TAG" "$release_asset" \ | |
| --title "$RELEASE_TITLE" \ | |
| --generate-notes \ | |
| --target "$GITHUB_SHA" | |
| fi | |
| deploy_github_pages: | |
| name: Deploy GitHub Pages | |
| needs: | |
| - publish_release_build | |
| - publish_github_release | |
| runs-on: macos-latest | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| permissions: | |
| pages: write | |
| id-token: write | |
| steps: | |
| - name: Configure GitHub Pages | |
| uses: actions/configure-pages@v6 | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v5 |