Merge pull request #132 from richardadonnell:feat/notification-click-… #8
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 Publish | |
| on: | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: release-main | |
| cancel-in-progress: false | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| environment: ${{ 'production' }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: app-v3/package-lock.json | |
| - name: Install dependencies | |
| working-directory: app-v3 | |
| run: npm ci | |
| - name: Resolve release metadata | |
| id: meta | |
| shell: bash | |
| run: | | |
| VERSION="$(node -p "require('./app-v3/package.json').version")" | |
| BUILD_TAG="v${VERSION}-main.${GITHUB_RUN_NUMBER}" | |
| RELEASE_NAME="upwork-job-scraper@${VERSION}-main.${GITHUB_RUN_NUMBER}" | |
| echo "tag=$BUILD_TAG" >> "$GITHUB_OUTPUT" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "release=$RELEASE_NAME" >> "$GITHUB_OUTPUT" | |
| - name: Build and package | |
| working-directory: app-v3 | |
| env: | |
| WXT_SENTRY_DSN: ${{ vars['WXT_SENTRY_DSN'] }} | |
| WXT_SENTRY_ENVIRONMENT: production | |
| WXT_SENTRY_RELEASE: ${{ steps.meta.outputs.release }} | |
| SENTRY_SOURCEMAPS: "true" | |
| SENTRY_UPLOAD_SOURCEMAPS_VITE: "false" | |
| run: npm run zip | |
| - name: Verify manifest version matches package version | |
| shell: bash | |
| run: | | |
| PACKAGE_VERSION="$(node -p "require('./app-v3/package.json').version")" | |
| MANIFEST_VERSION="$(node -p "require('./app-v3/.output/chrome-mv3/manifest.json').version")" | |
| echo "package.json version: $PACKAGE_VERSION" | |
| echo "manifest version: $MANIFEST_VERSION" | |
| if [[ "$PACKAGE_VERSION" != "$MANIFEST_VERSION" ]]; then | |
| echo "Version mismatch: app-v3/package.json and built manifest.json differ." | |
| exit 1 | |
| fi | |
| - name: Create or update GitHub release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| TAG="${{ steps.meta.outputs.tag }}" | |
| TITLE="Upwork Job Scraper main build v${{ steps.meta.outputs.version }} (#${{ github.run_number }})" | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release edit "$TAG" --title "$TITLE" | |
| else | |
| gh release create "$TAG" --title "$TITLE" --generate-notes | |
| fi | |
| - name: Locate Chrome ZIP | |
| id: zip | |
| shell: bash | |
| run: | | |
| ZIP_FILE="$(ls app-v3/.output/*-chrome.zip | head -n 1)" | |
| if [[ -z "$ZIP_FILE" ]]; then | |
| echo "No Chrome zip artifact found under app-v3/.output" | |
| exit 1 | |
| fi | |
| echo "zip_file=$ZIP_FILE" >> "$GITHUB_OUTPUT" | |
| - name: Upload ZIP to GitHub release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| gh release upload "${{ steps.meta.outputs.tag }}" "${{ steps.zip.outputs.zip_file }}" --clobber | |
| - name: Upload sourcemaps to Sentry | |
| env: | |
| SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
| SENTRY_ORG: ${{ vars['SENTRY_ORG'] }} | |
| SENTRY_PROJECT: ${{ vars['SENTRY_PROJECT'] }} | |
| SENTRY_RELEASE: ${{ steps.meta.outputs.release }} | |
| shell: bash | |
| run: | | |
| npx --yes @sentry/cli sourcemaps inject app-v3/.output/chrome-mv3 | |
| npx --yes @sentry/cli sourcemaps upload \ | |
| --release "$SENTRY_RELEASE" \ | |
| --url-prefix "~/" \ | |
| app-v3/.output/chrome-mv3 | |
| - name: Exchange refresh token for access token | |
| id: token | |
| env: | |
| CWS_CLIENT_ID: ${{ secrets['CWS_CLIENT_ID'] }} | |
| CWS_CLIENT_SECRET: ${{ secrets['CWS_CLIENT_SECRET'] }} | |
| CWS_REFRESH_TOKEN: ${{ secrets['CWS_REFRESH_TOKEN'] }} | |
| shell: bash | |
| run: | | |
| TOKEN_JSON="$(curl --fail --silent --show-error https://oauth2.googleapis.com/token \ | |
| -d client_id="$CWS_CLIENT_ID" \ | |
| -d client_secret="$CWS_CLIENT_SECRET" \ | |
| -d refresh_token="$CWS_REFRESH_TOKEN" \ | |
| -d grant_type=refresh_token)" | |
| ACCESS_TOKEN="$(echo "$TOKEN_JSON" | python -c "import json,sys; print(json.load(sys.stdin).get('access_token',''))")" | |
| if [[ -z "$ACCESS_TOKEN" ]]; then | |
| echo "Failed to obtain access token from refresh token flow." | |
| exit 1 | |
| fi | |
| echo "::add-mask::$ACCESS_TOKEN" | |
| echo "access_token=$ACCESS_TOKEN" >> "$GITHUB_OUTPUT" | |
| - name: Upload to Chrome Web Store (upload-only) | |
| env: | |
| ACCESS_TOKEN: ${{ steps.token.outputs.access_token }} | |
| CWS_PUBLISHER_ID: ${{ vars['CWS_PUBLISHER_ID'] }} | |
| CWS_EXTENSION_ID: ${{ vars['CWS_EXTENSION_ID'] }} | |
| ZIP_FILE: ${{ steps.zip.outputs.zip_file }} | |
| shell: bash | |
| run: | | |
| RESPONSE="$(curl --fail --silent --show-error \ | |
| -X POST \ | |
| -H "Authorization: Bearer $ACCESS_TOKEN" \ | |
| -H "Content-Type: application/zip" \ | |
| --data-binary "@$ZIP_FILE" \ | |
| "https://chromewebstore.googleapis.com/upload/v2/publishers/$CWS_PUBLISHER_ID/items/$CWS_EXTENSION_ID:upload")" | |
| echo "$RESPONSE" | |
| STATE="$(echo "$RESPONSE" | python -c "import json,sys; print(json.load(sys.stdin).get('uploadState',''))")" | |
| if [[ "$STATE" != "SUCCESS" && "$STATE" != "SUCCEEDED" ]]; then | |
| echo "Chrome Web Store upload did not return SUCCESS/SUCCEEDED." | |
| exit 1 | |
| fi | |
| - name: Manual publish reminder | |
| run: echo "Upload complete. Publish manually in the Chrome Web Store dashboard." |