Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add release actions #2155

Merged
merged 3 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
WEB_EXT_API_KEY=
WEB_EXT_API_SECRET=
68 changes: 68 additions & 0 deletions .github/workflows/release-after-signing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Generate Release (after signing)

on:
workflow_dispatch:

permissions:
contents: write

jobs:
release:
name: Generate Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- run: npm ci

### NOTE: This workflow continues the "Generate Release" workflow if it timed out.

- name: Firefox — Download Latest Signed XPI
run: node dev/download_signed_xpi.mjs

- name: Get Release Version
uses: actions/github-script@v7
id: get-version
with:
result-encoding: string
script: |
const fs = require('node:fs');
const { version } = JSON.parse(fs.readFileSync(('${{ github.workspace }}/manifest.json')));
const files = fs
.readdirSync('${{ github.workspace }}/web-ext-artifacts')
.filter(filePath => filePath.endsWith(`${version}.xpi`));
if (files.length === 0) {
throw new Error(`Could not find signed v${version} XPI! Has Mozilla reviewed it?`);
}
const releases = await github.paginate(github.rest.repos.listReleases, { owner: context.repo.owner, repo: context.repo.repo, });
if (releases.some(({ tag_name }) => tag_name === `v${version}`)) {
throw new Error(`Release v${version} already exists! Did you forget to bump the manifest.json version?`);
}
return version;

# - name: Chrome — Build
# run: npm run build
# - name: Chrome — Upload and Publish
# run: npx chrome-webstore-upload --source=web-ext-artifacts/new_xkit-${{ steps.get-version.outputs.result }}.zip
# env:
# EXTENSION_ID: ${{ secrets.CHROME_EXTENSION_ID }}
# CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }}
# CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }}
# REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }}

- name: Create Github release draft
uses: softprops/action-gh-release@v2
with:
name: New XKit ${{ steps.get-version.outputs.result }}
tag_name: v${{ steps.get-version.outputs.result }}
body: |
<!-- -->

**NOTE:** Firefox may complain about getting a connection error when clicking the below XPI link. If it does, right-click the link and select "Save Link As...", then navigate to `about:addons` and drag the file onto that screen to install New XKit.

For Chrome: Install from the [Chrome Web Store](https://new-xkit-extension.tumblr.com/chrome) instead of here.
files: web-ext-artifacts/*.xpi
draft: true
72 changes: 72 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Generate Release

on:
workflow_dispatch:

permissions:
contents: write

jobs:
sign-and-release:
name: Sign and Generate Release
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- run: npm ci

- name: Lint WebExtension
run: npm run lint

- name: Get Release Version
uses: actions/github-script@v7
id: get-version
with:
result-encoding: string
script: |
const fs = require('node:fs');
const { version } = JSON.parse(fs.readFileSync(('${{ github.workspace }}/manifest.json')));
const releases = await github.paginate(github.rest.repos.listReleases, { owner: context.repo.owner, repo: context.repo.repo, });
if (releases.some(({ tag_name }) => tag_name === `v${version}`)) {
throw new Error(`Release v${version} already exists! Did you forget to bump the manifest.json version?`);
}
return version;

- name: Firefox — Build and Sign
run: npm run sign
timeout-minutes: 30
env:
WEB_EXT_API_KEY: ${{ secrets.WEB_EXT_API_KEY }}
WEB_EXT_API_SECRET: ${{ secrets.WEB_EXT_API_SECRET }}
WEB_EXT_CHANNEL: unlisted

### NOTE: This workflow may time out here while waiting for Mozilla review.
### If this occurs, run the "Generate Release (after signing)" action once it is complete.

# - name: Chrome — Build
# run: npm run build
# - name: Chrome — Upload and Publish
# run: npx chrome-webstore-upload --source=web-ext-artifacts/new_xkit-${{ steps.get-version.outputs.result }}.zip
# env:
# EXTENSION_ID: ${{ secrets.CHROME_EXTENSION_ID }}
# CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }}
# CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }}
# REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }}

- name: Create Github release draft
uses: softprops/action-gh-release@v2
with:
name: New XKit ${{ steps.get-version.outputs.result }}
tag_name: v${{ steps.get-version.outputs.result }}
body: |
<!-- -->

**NOTE:** Firefox may complain about getting a connection error when clicking the below XPI link. If it does, right-click the link and select "Save Link As...", then navigate to `about:addons` and drag the file onto that screen to install New XKit.

For Chrome: Install from the [Chrome Web Store](https://new-xkit-extension.tumblr.com/chrome) instead of here.
files: web-ext-artifacts/*.xpi
draft: true
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ web-ext-artifacts/

*.iml
.idea/

.env
38 changes: 38 additions & 0 deletions dev/download_signed_xpi.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import "dotenv/config";
import jwt from "jsonwebtoken";
import assert from "node:assert";
import fs from "node:fs";
import path from "node:path";
import process from "node:process";

async function downloadXpi(addonId) {
const addonInfo = await fetch(`https://addons.mozilla.org/api/v5/addons/addon/${addonId}`, { headers: createAMOAuthHeaders() })
.then(response => response.json());

const {
latest_unlisted_version: {
file: { url },
},
} = addonInfo;

const file = await fetch(url, { headers: createAMOAuthHeaders() })
.then(response => response.arrayBuffer());

fs.mkdirSync("web-ext-artifacts", { recursive: true });
fs.writeFileSync(`web-ext-artifacts/${path.basename(url)}`, new Uint8Array(file), { flag: "w+" });
}

downloadXpi('@new-xkit');

// see https://mozilla.github.io/addons-server/topics/api/auth.html
function createAMOAuthHeaders() {
const { WEB_EXT_API_KEY, WEB_EXT_API_SECRET } = process.env;
assert(WEB_EXT_API_KEY && WEB_EXT_API_SECRET, "Missing addons.mozilla.org credentials in .env file!");

const payload = {
iss: WEB_EXT_API_KEY,
jti: Math.random().toString(),
};
const token = jwt.sign(payload, WEB_EXT_API_SECRET, { algorithm: "HS256", expiresIn: 60 });
return { Authorization: `JWT ${token}` };
}
Loading
Loading