Check Store Versions #40
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
| # Keeps `versions/stable.json`'s extension entry honest about what the | |
| # browser stores actually serve (store review lags a submitted release | |
| # by days). Polls the stores' own machine endpoints — the same update | |
| # contracts the browsers use, no page scraping — and patches ONLY the | |
| # `extension.stores` object on the feed when something changed. A store | |
| # whose lookup fails keeps its previous value (the patch merges | |
| # key-wise, never blanks). | |
| name: Check Store Versions | |
| on: | |
| schedule: | |
| - cron: '17 */6 * * *' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| env: | |
| R2_BUCKET: oh-updates | |
| CHROME_EXT_ID: ablaikadpbfblkmhpmbbnbbfjoibeejb | |
| EDGE_EXT_ID: gnbibobkkddlflknjkgcmokdlpddegpo | |
| FIREFOX_SLUG: open-headers | |
| jobs: | |
| check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Check R2 credentials | |
| id: r2 | |
| run: | | |
| if [ -n "$R2_ACCOUNT_ID" ] && [ -n "$R2_ACCESS_KEY_ID" ] && [ -n "$R2_SECRET_ACCESS_KEY" ]; then | |
| echo "enabled=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "enabled=false" >> $GITHUB_OUTPUT | |
| echo "::warning::R2 secrets not configured — store versions not published" | |
| fi | |
| env: | |
| R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} | |
| R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| - name: Look up published store versions | |
| if: steps.r2.outputs.enabled == 'true' | |
| id: stores | |
| run: | | |
| # Chrome speaks the CRX update-check protocol (the response's | |
| # <updatecheck version="..."> is the live version); Edge and | |
| # Firefox expose store-listing JSON. | |
| CHROME=$(curl -fsS --max-time 30 "https://clients2.google.com/service/update2/crx?response=updatecheck&acceptformat=crx3&prodversion=138.0.0.0&x=id%3D${CHROME_EXT_ID}%26uc" 2>/dev/null \ | |
| | sed -n 's/.*updatecheck[^>]*version="\([0-9][0-9.]*\)".*/\1/p' | head -1) | |
| EDGE=$(curl -fsS --max-time 30 "https://microsoftedge.microsoft.com/addons/getproductdetailsbycrxid/${EDGE_EXT_ID}" 2>/dev/null | jq -r '.version // empty') | |
| FIREFOX=$(curl -fsS --max-time 30 "https://addons.mozilla.org/api/v5/addons/addon/${FIREFOX_SLUG}/" 2>/dev/null | jq -r '.current_version.version // empty') | |
| PATCH='{}' | |
| for pair in "chrome=$CHROME" "edge=$EDGE" "firefox=$FIREFOX"; do | |
| KEY="${pair%%=*}"; VALUE="${pair#*=}" | |
| if [ -n "$VALUE" ]; then | |
| PATCH=$(echo "$PATCH" | jq -c --arg k "$KEY" --arg v "$VALUE" '. + {($k): $v}') | |
| else | |
| echo "::warning::${KEY} store lookup failed — keeping the previous value" | |
| fi | |
| done | |
| echo "patch=$PATCH" >> $GITHUB_OUTPUT | |
| echo "Store versions: $PATCH" | |
| - name: Update feed when versions changed | |
| if: steps.r2.outputs.enabled == 'true' && steps.stores.outputs.patch != '{}' | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} | |
| AWS_REQUEST_CHECKSUM_CALCULATION: when_required | |
| AWS_RESPONSE_CHECKSUM_VALIDATION: when_required | |
| STORES_PATCH: ${{ steps.stores.outputs.patch }} | |
| run: | | |
| if ! curl -fsS "https://updates.openheaders.com/versions/stable.json" -o current.json; then | |
| echo '{}' > current.json | |
| fi | |
| node scripts/patch-versions-entry.mjs current.json extension \ | |
| "{\"stores\":${STORES_PATCH}}" > patched.json | |
| if cmp -s current.json patched.json; then | |
| echo "Store versions unchanged — nothing to upload" | |
| exit 0 | |
| fi | |
| cat patched.json | |
| aws s3 cp patched.json "s3://${R2_BUCKET}/versions/stable.json" \ | |
| --endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" --region auto \ | |
| --content-type "application/json" \ | |
| --cache-control "public, max-age=300, must-revalidate" \ | |
| --no-progress |