aboutsummaryrefslogtreecommitdiff
path: root/.github
diff options
context:
space:
mode:
authorDarius Jahandarie <djahandarie@gmail.com>2023-03-18 11:29:45 +0900
committerGitHub <noreply@github.com>2023-03-18 11:29:45 +0900
commite7a6f0354b8c38046e449566a371e366ef6b6889 (patch)
treecd3b2b7d30b8dac0ecbd4ebc91b9d1da8da36819 /.github
parent0314a8620f952aa5b0129e93f2d0956b0e0cc7c2 (diff)
parent1dd47d0876833c1d61572577ae5b9d2215578c07 (diff)
Merge pull request #92 from themoeway/cd
Add CD to build and publish extension to Chrome & Firefox stores
Diffstat (limited to '.github')
-rw-r--r--.github/release.yml17
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--.github/workflows/create-prerelease-on-tag.yml35
-rw-r--r--.github/workflows/publish-chrome-development.yml100
-rw-r--r--.github/workflows/publish-chrome.yml100
-rw-r--r--.github/workflows/publish-firefox-development.yml86
-rw-r--r--.github/workflows/publish-firefox.yml34
-rw-r--r--.github/workflows/touch-google-refresh-token.yml16
8 files changed, 390 insertions, 2 deletions
diff --git a/.github/release.yml b/.github/release.yml
new file mode 100644
index 00000000..c3cb6841
--- /dev/null
+++ b/.github/release.yml
@@ -0,0 +1,17 @@
+changelog:
+ exclude:
+ labels:
+ - kind/meta
+ categories:
+ - title: Breaking Changes
+ labels:
+ - kind/breaking-change
+ - title: Enhancement
+ labels:
+ - kind/enhancement
+ - title: Bug Fixes
+ labels:
+ - kind/bug
+ - title: Dependencies
+ labels:
+ - area/dependencies
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 99f3f518..3b7fc69c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,9 +14,9 @@ jobs:
uses: actions/checkout@v3
- name: Setup node
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
with:
- node-version: "16.x"
+ node-version-file: ".node-version"
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/create-prerelease-on-tag.yml b/.github/workflows/create-prerelease-on-tag.yml
new file mode 100644
index 00000000..a2d5fc57
--- /dev/null
+++ b/.github/workflows/create-prerelease-on-tag.yml
@@ -0,0 +1,35 @@
+name: Create prerelease on tag
+on:
+ push:
+ tags:
+ - "*.*.*.*"
+ workflow_dispatch:
+permissions:
+ contents: write
+jobs:
+ build-release-publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Validate manifest.json of the extension
+ uses: cardinalby/schema-validator-action@c2da05377e89dd0c9b7be9420da0b3534b1efcce # pin@v1
+ with:
+ file: ext/manifest.json
+ schema: "https://json.schemastore.org/webextension.json"
+
+ - name: Setup node
+ uses: actions/setup-node@v3
+ with:
+ node-version-file: ".node-version"
+
+ - name: Lint
+ run: npm run-script build
+ shell: bash
+
+ - name: Release
+ uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # pin@v0.1.15
+ with:
+ generate_release_notes: true
+ prerelease: true
+ files: builds/*
diff --git a/.github/workflows/publish-chrome-development.yml b/.github/workflows/publish-chrome-development.yml
new file mode 100644
index 00000000..669a6b57
--- /dev/null
+++ b/.github/workflows/publish-chrome-development.yml
@@ -0,0 +1,100 @@
+name: publish-chrome-development
+on:
+ release:
+ types: [prereleased]
+ workflow_dispatch:
+ inputs:
+ attemptNumber:
+ description: "Attempt number"
+ required: false
+ default: "1"
+ maxAttempts:
+ description: "Max attempts"
+ required: false
+ default: "10"
+permissions:
+ actions: write
+ contents: read
+jobs:
+ upload-on-webstore:
+ runs-on: ubuntu-latest
+ environment: cd
+ outputs:
+ result: ${{ steps.webStorePublish.outcome }}
+ releaseUploadUrl: ${{ steps.getZipAsset.outputs.releaseUploadUrl }}
+ steps:
+ - name: Get the next attempt number
+ id: getNextAttemptNumber
+ uses: cardinalby/js-eval-action@b34865f1d9cfdf35356013627474857cfe0d5091 # pin@v1.0.7
+ env:
+ attemptNumber: ${{ github.event.inputs.attemptNumber }}
+ maxAttempts: ${{ github.event.inputs.maxAttempts }}
+ with:
+ expression: |
+ {
+ const
+ attempt = parseInt(env.attemptNumber),
+ max = parseInt(env.maxAttempts);
+ assert(attempt && max && max >= attempt);
+ return attempt < max ? attempt + 1 : '';
+ }
+
+ - uses: actions/checkout@v3
+
+ - uses: robinraju/release-downloader@768b85c8d69164800db5fc00337ab917daf3ce68 # pin@v1.7
+ with:
+ tag: ${{ github.ref_name }}
+ fileName: "*"
+
+ - name: Fetch Google API access token
+ id: fetchAccessToken
+ uses: cardinalby/google-api-fetch-token-action@24c99245e2a2494cc4c4b1037203d319a184b15b # pin@v1.0.3
+ with:
+ clientId: ${{ secrets.G_CLIENT_ID }}
+ clientSecret: ${{ secrets.G_CLIENT_SECRET }}
+ refreshToken: ${{ secrets.G_REFRESH_TOKEN }}
+
+ - name: Upload to Google Web Store
+ id: webStoreUpload
+ continue-on-error: true
+ uses: cardinalby/webext-buildtools-chrome-webstore-upload-action@8db7a005529498d95d3e2e0166f6f4050d2b96a5 # pin@v1.0.10
+ with:
+ zipFilePath: builds/yomitan-chrome-dev.zip
+ extensionId: ${{ secrets.G_DEVELOPMENT_EXTENSION_ID }}
+ apiAccessToken: ${{ steps.fetchAccessToken.outputs.accessToken }}
+ waitForUploadCheckCount: 10
+ waitForUploadCheckIntervalMs: 180000 # 3 minutes
+
+ # Schedule a next attempt if store refused to accept new version because it
+ # still has a previous one in review
+ - name: Start the next attempt with the delay
+ uses: aurelien-baudet/workflow-dispatch@93e95b157d791ae7f42aef8f8a0d3d723eba1c31 # pin@v2
+ if: |
+ steps.getNextAttemptNumber.outputs.result &&
+ steps.webStoreUpload.outputs.inReviewError == 'true'
+ with:
+ workflow: delay
+ token: ${{ secrets.GITHUB_TOKEN }}
+ wait-for-completion: false
+ inputs: |
+ {
+ "attemptNumber": "${{ steps.getNextAttemptNumber.outputs.result }}",
+ "maxAttempts": "${{ github.event.inputs.maxAttempts }}",
+ "workflow": "${{ github.workflow }}"
+ }
+
+ - name: Abort on unrecoverable upload error
+ if: |
+ !steps.webStoreUpload.outputs.newVersion &&
+ steps.webStoreUpload.outputs.sameVersionAlreadyUploadedError != 'true'
+ run: exit 1
+
+ - name: Publish on Google Web Store
+ id: webStorePublish
+ if: |
+ steps.webStoreUpload.outputs.newVersion ||
+ steps.webStoreUpload.outputs.sameVersionAlreadyUploadedError == 'true'
+ uses: cardinalby/webext-buildtools-chrome-webstore-publish-action@d39ebd4ab4ea4b44498bf5fc34d4b3db7706f1ed # pin@v1.0.7
+ with:
+ extensionId: ${{ secrets.G_DEVELOPMENT_EXTENSION_ID }}
+ apiAccessToken: ${{ steps.fetchAccessToken.outputs.accessToken }}
diff --git a/.github/workflows/publish-chrome.yml b/.github/workflows/publish-chrome.yml
new file mode 100644
index 00000000..cb47d565
--- /dev/null
+++ b/.github/workflows/publish-chrome.yml
@@ -0,0 +1,100 @@
+name: publish-chrome
+on:
+ release:
+ types: [released]
+ workflow_dispatch:
+ inputs:
+ attemptNumber:
+ description: "Attempt number"
+ required: false
+ default: "1"
+ maxAttempts:
+ description: "Max attempts"
+ required: false
+ default: "10"
+permissions:
+ actions: write
+ contents: read
+jobs:
+ upload-on-webstore:
+ runs-on: ubuntu-latest
+ environment: cd
+ outputs:
+ result: ${{ steps.webStorePublish.outcome }}
+ releaseUploadUrl: ${{ steps.getZipAsset.outputs.releaseUploadUrl }}
+ steps:
+ - name: Get the next attempt number
+ id: getNextAttemptNumber
+ uses: cardinalby/js-eval-action@b34865f1d9cfdf35356013627474857cfe0d5091 # pin@v1.0.7
+ env:
+ attemptNumber: ${{ github.event.inputs.attemptNumber }}
+ maxAttempts: ${{ github.event.inputs.maxAttempts }}
+ with:
+ expression: |
+ {
+ const
+ attempt = parseInt(env.attemptNumber),
+ max = parseInt(env.maxAttempts);
+ assert(attempt && max && max >= attempt);
+ return attempt < max ? attempt + 1 : '';
+ }
+
+ - uses: actions/checkout@v3
+
+ - uses: robinraju/release-downloader@768b85c8d69164800db5fc00337ab917daf3ce68 # pin@v1.7
+ with:
+ tag: ${{ github.ref_name }}
+ fileName: "*"
+
+ - name: Fetch Google API access token
+ id: fetchAccessToken
+ uses: cardinalby/google-api-fetch-token-action@24c99245e2a2494cc4c4b1037203d319a184b15b # pin@v1.0.3
+ with:
+ clientId: ${{ secrets.G_CLIENT_ID }}
+ clientSecret: ${{ secrets.G_CLIENT_SECRET }}
+ refreshToken: ${{ secrets.G_REFRESH_TOKEN }}
+
+ - name: Upload to Google Web Store
+ id: webStoreUpload
+ continue-on-error: true
+ uses: cardinalby/webext-buildtools-chrome-webstore-upload-action@8db7a005529498d95d3e2e0166f6f4050d2b96a5 # pin@v1.0.10
+ with:
+ zipFilePath: builds/yomitan-chrome.zip
+ extensionId: ${{ secrets.G_STABLE_EXTENSION_ID }}
+ apiAccessToken: ${{ steps.fetchAccessToken.outputs.accessToken }}
+ waitForUploadCheckCount: 10
+ waitForUploadCheckIntervalMs: 180000 # 3 minutes
+
+ # Schedule a next attempt if store refused to accept new version because it
+ # still has a previous one in review
+ - name: Start the next attempt with the delay
+ uses: aurelien-baudet/workflow-dispatch@93e95b157d791ae7f42aef8f8a0d3d723eba1c31 # pin@v2
+ if: |
+ steps.getNextAttemptNumber.outputs.result &&
+ steps.webStoreUpload.outputs.inReviewError == 'true'
+ with:
+ workflow: delay
+ token: ${{ secrets.GITHUB_TOKEN }}
+ wait-for-completion: false
+ inputs: |
+ {
+ "attemptNumber": "${{ steps.getNextAttemptNumber.outputs.result }}",
+ "maxAttempts": "${{ github.event.inputs.maxAttempts }}",
+ "workflow": "${{ github.workflow }}"
+ }
+
+ - name: Abort on unrecoverable upload error
+ if: |
+ !steps.webStoreUpload.outputs.newVersion &&
+ steps.webStoreUpload.outputs.sameVersionAlreadyUploadedError != 'true'
+ run: exit 1
+
+ - name: Publish on Google Web Store
+ id: webStorePublish
+ if: |
+ steps.webStoreUpload.outputs.newVersion ||
+ steps.webStoreUpload.outputs.sameVersionAlreadyUploadedError == 'true'
+ uses: cardinalby/webext-buildtools-chrome-webstore-publish-action@d39ebd4ab4ea4b44498bf5fc34d4b3db7706f1ed # pin@v1.0.7
+ with:
+ extensionId: ${{ secrets.G_STABLE_EXTENSION_ID }}
+ apiAccessToken: ${{ steps.fetchAccessToken.outputs.accessToken }}
diff --git a/.github/workflows/publish-firefox-development.yml b/.github/workflows/publish-firefox-development.yml
new file mode 100644
index 00000000..0ed07326
--- /dev/null
+++ b/.github/workflows/publish-firefox-development.yml
@@ -0,0 +1,86 @@
+# For the Firefox development addon, people install it manually,
+# and updates are distributed via the JSON file created in this
+# action which is stored in the metadata branch of this repo.
+
+name: publish-firefox-development
+on:
+ release:
+ types: [prereleased]
+permissions:
+ contents: write
+jobs:
+ build-signed-xpi-asset:
+ needs: ensure-zip
+ runs-on: ubuntu-latest
+ environment: cd
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: robinraju/release-downloader@768b85c8d69164800db5fc00337ab917daf3ce68 # pin@v1.7
+ with:
+ release: ${{ github.event.release.id }}
+ fileName: "*"
+
+ - name: Sign Firefox xpi for offline distribution
+ id: ffSignXpi
+ continue-on-error: true
+ uses: cardinalby/webext-buildtools-firefox-sign-xpi-action@94a2e58141e33c4306a72a93f191e8540189df92 # pin@v1.0.6
+ with:
+ timeoutMs: 1200000
+ extensionId: ${{ secrets.FF_OFFLINE_EXT_ID }}
+ zipFilePath: builds/yomitan-firefox-dev.zip
+ xpiFilePath: builds/yomitan-firefox-dev.xpi
+ jwtIssuer: ${{ secrets.FF_JWT_ISSUER }}
+ jwtSecret: ${{ secrets.FF_JWT_SECRET }}
+
+ - name: Abort on sign error
+ if: |
+ steps.ffSignXpi.outcome == 'failure' &&
+ steps.ffSignXpi.outputs.sameVersionAlreadyUploadedError != 'true'
+ run: exit 1
+
+ - name: Upload offline xpi release asset
+ id: uploadReleaseAsset
+ if: steps.ffSignXpi.outcome == 'success'
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ github.event.release.upload_url }}
+ asset_path: builds/yomitan-firefox.xpi
+ asset_name: yomitan-firefox.xpi
+ asset_content_type: application/x-xpinstall
+
+ # update update.json so that all people who have the dev version installed get the new update
+
+ - uses: actions/checkout@v3
+ with:
+ ref: metadata
+
+ - name: Recreate update.json
+ run: |
+ cat > update.json << EOF
+ {
+ "addons": {
+ "{2d13e145-294e-4ead-9bce-b4644b203a00}": {
+ "updates": [
+ {
+ "version": "${{ github.event.release.name }}",
+ "update_link": "${{ uploadReleaseAsset.browser_download_url }}"
+ }
+ ]
+ }
+ }
+ }
+ EOF
+
+ - name: Commit files
+ run: |
+ git config --local user.email "github-actions[bot]@users.noreply.github.com"
+ git config --local user.name "github-actions[bot]"
+ git commit -a -m "${{ github.event.release.name }} - ${{ github.event.release.html_url }}"
+
+ - name: Push changes
+ uses: ad-m/github-push-action@0fafdd62b84042d49ec0cb92d9cac7f7ce4ec79e # pin@master
+ with:
+ branch: metadata
diff --git a/.github/workflows/publish-firefox.yml b/.github/workflows/publish-firefox.yml
new file mode 100644
index 00000000..7b2037af
--- /dev/null
+++ b/.github/workflows/publish-firefox.yml
@@ -0,0 +1,34 @@
+name: publish-firefox
+on:
+ release:
+ types: [released]
+permissions:
+ contents: read
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ environment: cd
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: robinraju/release-downloader@768b85c8d69164800db5fc00337ab917daf3ce68 # pin@v1.7
+ with:
+ tag: ${{ github.ref_name }}
+ fileName: "*"
+
+ - name: Deploy to Firefox Addons
+ id: addonsDeploy
+ uses: cardinalby/webext-buildtools-firefox-addons-action@924ad87df7e4af50a654c164ad9e498dce260ffa # pin@v1.0.9
+ continue-on-error: true
+ with:
+ zipFilePath: builds/yomitan-firefox.zip
+ extensionId: ${{ secrets.FF_EXTENSION_ID }}
+ jwtIssuer: ${{ secrets.FF_JWT_ISSUER }}
+ jwtSecret: ${{ secrets.FF_JWT_SECRET }}
+
+ - name: Abort on upload error
+ if: |
+ steps.addonsDeploy.outcome == 'failure' &&
+ steps.addonsDeploy.outputs.sameVersionAlreadyUploadedError != 'true' &&
+ steps.addonsDeploy.outputs.timeoutError != 'true'
+ run: exit 1
diff --git a/.github/workflows/touch-google-refresh-token.yml b/.github/workflows/touch-google-refresh-token.yml
new file mode 100644
index 00000000..9c4e2ec9
--- /dev/null
+++ b/.github/workflows/touch-google-refresh-token.yml
@@ -0,0 +1,16 @@
+name: Touch google token
+on:
+ schedule:
+ - cron: "0 3 2 * *" # At 03:00 on day-of-month 2
+ workflow_dispatch:
+permissions: {}
+jobs:
+ fetchToken:
+ runs-on: ubuntu-latest
+ environment: cd
+ steps:
+ - uses: cardinalby/google-api-fetch-token-action@24c99245e2a2494cc4c4b1037203d319a184b15b # pin@v1.0.3
+ with:
+ clientId: ${{ secrets.G_CLIENT_ID }}
+ clientSecret: ${{ secrets.G_CLIENT_SECRET }}
+ refreshToken: ${{ secrets.G_REFRESH_TOKEN }}