Skip to content

Commit 1704d67

Browse files
committed
Run signed builds on git tags and attach to Release using a separate workflow
1 parent b6a5f3c commit 1704d67

4 files changed

Lines changed: 143 additions & 88 deletions

File tree

Lines changed: 34 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
name: "Browser Extensions"
1+
name: "Build Browser Extensions" # If you change this name, you'll also need to update the release.yaml job
22

33
on:
44
workflow_dispatch:
5-
release:
6-
types: [published]
75
pull_request:
86
paths:
97
- browser-extension/**
@@ -14,24 +12,25 @@ on:
1412
- .github/workflows/**
1513
branches:
1614
- '**'
17-
tags-ignore:
18-
# Don't run again on tags since we already run on all branches.
19-
- '**'
15+
tags:
16+
# Only run on release tags:
17+
- 'v[0-9]+.[0-9]+.[0-9]+'
18+
2019
jobs:
2120
build-extensions:
2221
name: Build and bundle the browser extensions
22+
# Since we run on both branch pushes and PRs, don't do a duplicated run if the PR is for a branch in the local repo:
23+
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
2324
runs-on: ubuntu-latest
2425
defaults:
2526
run:
2627
shell: bash
2728
working-directory: browser-extension
28-
outputs:
29-
version: ${{ steps.get-version.outputs.version }}
3029
steps:
3130
- name: Check out repository code
3231
uses: actions/checkout@v4
3332
with:
34-
fetch-depth: 0 # Fetch all history for tags
33+
fetch-depth: 0 # Fetch all history to pull git tags
3534

3635
- name: Set up Node.js
3736
uses: actions/setup-node@v4
@@ -52,7 +51,7 @@ jobs:
5251
echo "version=$VERSION" >> $GITHUB_OUTPUT
5352
echo "Using version: $VERSION"
5453
55-
- name: Build extensions
54+
- name: Build our browser extensions
5655
run: |
5756
npm run build
5857
@@ -71,9 +70,10 @@ jobs:
7170
npm run package-firefox
7271
7372
- name: Package Firefox extension (signed for release)
73+
id: sign-firefox-extension
7474
# Only sign versions that we actually intend to release. Mozilla does not allow the same version
7575
# number to be signed multiple times, so duplicated build attempts will fail.
76-
if: ${{ github.event_name == 'release' }}
76+
if: ${{ github.ref_type == 'tag' }}
7777
env:
7878
WEB_EXT_API_KEY: ${{ secrets.FIREFOX_JWT_ISSUER }}
7979
WEB_EXT_API_SECRET: ${{ secrets.FIREFOX_JWT_SECRET }}
@@ -103,56 +103,37 @@ jobs:
103103
104104
echo "✅ Manifest validation passed - Version: $CHROME_VERSION"
105105
106+
- name: Rename Chrome extension
107+
run: |
108+
mv ./build/chrome-extension.zip ./build/chrome-extension-v${{ steps.get-version.outputs.version }}.zip
109+
110+
- name: Rename Firefox extension (unsigned)
111+
run: |
112+
mv ./build/firefox-extension.zip ./build/firefox-extension-unsigned-v${{ steps.get-version.outputs.version }}.zip
113+
114+
- name: Rename Firefox extension (signed)
115+
if: ${{ steps.sign-firefox-extension.outcome != 'skipped' }}
116+
run: |
117+
mv ./build/streamdeck_googlemeet-${{ steps.get-version.outputs.version }}.xpi ./build/firefox-extension-v${{ steps.get-version.outputs.version }}.xpi
118+
106119
- name: Upload Chrome extension artifact
107120
uses: actions/upload-artifact@v4
108121
with:
109-
name: chrome-extension-v${{ steps.get-version.outputs.version }}
110-
path: browser-extension/build/chrome-extension.zip
122+
# If you change this artifact name or filename, you must also update the release job's download-artifact steps.
123+
name: chrome-extension
124+
path: browser-extension/build/chrome-extension-v${{ steps.get-version.outputs.version }}.zip
111125

112126
- name: Upload Firefox extension artifact (unsigned)
113127
uses: actions/upload-artifact@v4
114128
with:
115-
name: firefox-extension-unsigned-v${{ steps.get-version.outputs.version }}
116-
path: browser-extension/build/firefox-extension.zip
129+
# If you change this artifact name or filename, you must also update the release job's download-artifact steps.
130+
name: firefox-extension-unsigned
131+
path: browser-extension/build/firefox-extension-unsigned-v${{ steps.get-version.outputs.version }}.zip
117132

118133
- name: Upload Firefox extension artifact (signed)
119-
if: ${{ github.event_name == 'release' }}
134+
if: ${{ steps.sign-firefox-extension.outcome != 'skipped' }}
120135
uses: actions/upload-artifact@v4
121136
with:
122-
name: firefox-extension-signed-v${{ steps.get-version.outputs.version }}
123-
path: browser-extension/build/streamdeck_googlemeet-${{ steps.get-version.outputs.version }}.xpi
124-
125-
attach-to-release:
126-
name: Attach artifacts to the GitHub Release
127-
if: ${{ github.event_name == 'release' }}
128-
runs-on: ubuntu-latest
129-
needs: [build-extensions]
130-
permissions:
131-
contents: write # Needed for softprops/action-gh-release
132-
steps:
133-
- name: Download Chrome extension
134-
uses: actions/download-artifact@v4
135-
with:
136-
name: chrome-extension-v${{ needs.build-extensions.outputs.version }}
137-
path: ./artifacts
138-
139-
- name: Rename Chrome extension
140-
run: |
141-
mv ./artifacts/chrome-extension.zip ./chrome-extension-v${{ needs.build-extensions.outputs.version }}.zip
142-
143-
- name: Download Firefox extension
144-
uses: actions/download-artifact@v4
145-
with:
146-
name: firefox-extension-signed-v${{ needs.build-extensions.outputs.version }}
147-
path: ./artifacts
148-
149-
- name: Rename Firefox extension
150-
run: |
151-
mv ./artifacts/streamdeck_googlemeet-${{ needs.build-extensions.outputs.version }}.xpi ./firefox-extension-v${{ needs.build-extensions.outputs.version }}.xpi
152-
153-
- name: Attach all artifacts to release
154-
uses: softprops/action-gh-release@v2
155-
with:
156-
files: |
157-
./chrome-extension-v${{ needs.build-extensions.outputs.version }}.zip
158-
./firefox-extension-v${{ needs.build-extensions.outputs.version }}.xpi
137+
# If you change this artifact name or filename, you must also update the release job's download-artifact steps.
138+
name: firefox-extension-signed
139+
path: browser-extension/build/firefox-extension-v${{ steps.get-version.outputs.version }}.xpi

.github/workflows/release.yaml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# This job runs when a GitHub Release is created. It finds our build artifacts for the CI jobs
2+
# that ran against this release's associated git tag, and attaches those artifacts to our GitHub
3+
# Release. We use this multi-step procedure (rather than just doing the build when the Release is
4+
# created) so that artifacts can be tested and validated before they become available on the Releases
5+
# page where users are more likely to download them even if they're marked as pre-release.
6+
7+
name: "Prepare GitHub Release"
8+
9+
on:
10+
workflow_dispatch:
11+
release:
12+
types: [published]
13+
14+
jobs:
15+
attach-artifacts:
16+
name: Attach artifacts from git tag builds to the GitHub Release
17+
runs-on: ubuntu-latest
18+
permissions:
19+
actions: read # Needed for `gh run list`
20+
contents: write # Needed for softprops/action-gh-release
21+
steps:
22+
- name: Check out repository code
23+
uses: actions/checkout@v4
24+
25+
# Find the GitHub Action run IDs of the most recent build jobs for our release's git tag:
26+
- name: "Find GHA run IDs for this release's git tag"
27+
id: get-workflow-id
28+
env:
29+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
run: |
31+
function getRunId() {
32+
gh run list \
33+
--branch "${{ github.event.release.tag_name }}" \
34+
--workflow "$1" \
35+
--limit 1 \
36+
--json "status,conclusion,createdAt,databaseId,event,headBranch,headSha,number,startedAt,status,updatedAt,url" \
37+
--event push | tee build_workflow_run.json
38+
39+
TAG_RUN_ID=$( jq 'if .[0].conclusion == "success" then .[0].databaseId else halt end' build_workflow_run.json )
40+
if [[ -z "$TAG_RUN_ID" ]]; then
41+
echo "❌ The most recent build for a tag matching this GitHub Release name is either missing, incomplete, or unsuccessful!"
42+
echo "Check the build history for tag '${{ github.event.release.tag_name }}' to see if it's still running or failed."
43+
exit 1
44+
fi
45+
}
46+
47+
getRunId "Build Browser Extensions"
48+
extensions_run_id="$TAG_RUN_ID"
49+
echo "Workflow run ID for browser extensions: ${extensions_run_id}"
50+
echo "extensions_run_id=$extensions_run_id" >> $GITHUB_OUTPUT
51+
52+
getRunId "Build Stream Deck Plugin"
53+
plugin_run_id="$TAG_RUN_ID"
54+
echo "Workflow run ID for Stream Deck plugin: ${plugin_run_id}"
55+
echo "plugin_run_id=$plugin_run_id" >> $GITHUB_OUTPUT
56+
57+
- name: Download Chrome extension
58+
uses: actions/download-artifact@v4
59+
with:
60+
# Artifact name must match the `actions/upload-artifact` steps from the build job
61+
name: chrome-extension
62+
run-id: ${{ steps.get-workflow-id.outputs.extensions_run_id }}
63+
github-token: ${{ secrets.GITHUB_TOKEN }}
64+
path: ./artifacts
65+
66+
- name: Download Firefox extension
67+
uses: actions/download-artifact@v4
68+
with:
69+
# Artifact name must match the `actions/upload-artifact` steps from the build job
70+
name: firefox-extension-signed
71+
run-id: ${{ steps.get-workflow-id.outputs.extensions_run_id }}
72+
github-token: ${{ secrets.GITHUB_TOKEN }}
73+
path: ./artifacts
74+
75+
- name: Download Stream Deck Plugin
76+
uses: actions/download-artifact@v4
77+
with:
78+
# Artifact name must match the `actions/upload-artifact` steps from the build job
79+
name: com.chrisregado.googlemeet.streamDeckPlugin
80+
run-id: ${{ steps.get-workflow-id.outputs.plugin_run_id }}
81+
github-token: ${{ secrets.GITHUB_TOKEN }}
82+
path: ./artifacts
83+
84+
- name: Attach artifacts to release
85+
uses: softprops/action-gh-release@v2
86+
with:
87+
# Artifact filenames must match the `actions/upload-artifact` steps from the build jobs
88+
files: |
89+
./artifacts/chrome-extension-${{ github.event.release.tag_name }}.zip
90+
./artifacts/firefox-extension-${{ github.event.release.tag_name }}.xpi
91+
./artifacts/com.chrisregado.googlemeet.streamDeckPlugin

.github/workflows/streamdeck-plugin-build.yml

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
name: "Stream Deck Plugin"
1+
name: "Build Stream Deck Plugin" # If you change this name, you'll also need to update the release.yaml job
22

33
on:
44
workflow_dispatch:
5-
release:
6-
types: [published]
75
pull_request:
86
paths:
97
- streamdeck-plugin/**
@@ -16,9 +14,9 @@ on:
1614
- .github/workflows/**
1715
branches:
1816
- '**'
19-
tags-ignore:
20-
# Don't run again on tags since we already run on all branches.
21-
- '**'
17+
tags:
18+
# Only run on release tags:
19+
- 'v[0-9]+.[0-9]+.[0-9]+'
2220

2321
jobs:
2422
build-plugin:
@@ -30,6 +28,8 @@ jobs:
3028
- os: windows
3129
runs_on: windows-latest
3230
name: Build ${{ matrix.os }} Stream Deck Plugin
31+
# Since we run on both branch pushes and PRs, don't do a duplicated run if the PR is for a branch in the local repo:
32+
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
3333
runs-on: ${{ matrix.runs_on }}
3434
defaults:
3535
run:
@@ -88,23 +88,3 @@ jobs:
8888
with:
8989
name: com.chrisregado.googlemeet.streamDeckPlugin
9090
path: output/com.chrisregado.googlemeet.streamDeckPlugin
91-
92-
attach-to-release:
93-
name: Attach artifacts to release
94-
if: ${{ github.event_name == 'release' }}
95-
runs-on: ubuntu-latest
96-
needs: [bundle-streamdeck-distributable]
97-
permissions:
98-
contents: write # Needed for softprops/action-gh-release
99-
steps:
100-
- name: Download Stream Deck plugin
101-
uses: actions/download-artifact@v4
102-
with:
103-
name: com.chrisregado.googlemeet.streamDeckPlugin
104-
path: ./artifacts
105-
106-
- name: Attach artifacts to release
107-
uses: softprops/action-gh-release@v2
108-
with:
109-
files: |
110-
./artifacts/com.chrisregado.googlemeet.streamDeckPlugin

RELEASE_INSTRUCTIONS.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ Finally, we'll add auth tokens from the Firefox Add-on portal as GitHub Action s
3535
Follow these steps each time you want to release a new version of the plugin and/or browser extension:
3636

3737
1. Manually update the version number of the Stream Deck plugin by editing `com.chrisregado.googlemeet.sdPlugin/manifest.json` and changing the `Version` field. Make sure that change gets merged into `master`. (We have CI jobs to manage version numbers for the browser extensions, so you don't need to touch those.)
38-
2. On the Github page for your repo, click "Releases". (e.g. https://github.com/ChrisRegado/streamdeck-googlemeet/releases)
39-
3. Click "Draft a new release".
40-
4. Click the "Tag" button. We use semantic versioning with a "v" prefix for our releases. Enter a new version string (e.g. `v1.2.3`) and click "Create a new tag: v1.2.3 on publish". (Or if you already manually pushed a properly-formatted tag to origin, you can pick that tag in the dropdown.)
41-
5. Use the same version string for the "Release title", and enter a description summarizing notable changes in this release.
42-
6. Select the "Set as a pre-release" checkbox near the bottom of the page.
43-
7. Click "Publish release".
44-
8. Wait for our CI jobs to complete. If all goes well, in a few minutes you should see 3 attachments appear on the release: the `com.chrisregado.googlemeet.streamDeckPlugin` plugin, a zip of the Chrome extension, and an `.xpi` file for the Firefox extension.
45-
9. Do a final manual validation of those release artifacts. (Download and install the plugin and browser extension, and verify basic functionality.)
46-
10. Edit the release, uncheck the "Set as a pre-release" checkbox at the bottom of the page, select the "Set as the latest release" checkbox, and click "Update release".
38+
2. Tag the commit you wish to release and push it to GitHub. We use semantic versioning with a "v" prefix for our releases. For example: `git checkout master && git tag v1.2.3 && git push origin tag v1.2.3`
39+
3. CI jobs should automatically launch against that tag to build the [Stream Deck plugin](https://github.com/ChrisRegado/streamdeck-googlemeet/actions/workflows/streamdeck-plugin-build.yml) and [browser extensions](https://github.com/ChrisRegado/streamdeck-googlemeet/actions/workflows/browser-extension-build.yml). (The list of workflow runs should show one copy of each of those two jobs with your `v1.2.3` tag.) Wait for them to complete successfully.
40+
4. Click into those two build jobs, and on each job's "Summary" tab, download our build artifacts. The browser extension build job should have `chrome-extension` and `firefox-extension-signed` artifacts, and the plugin build job should have `com.chrisregado.googlemeet.streamDeckPlugin`.
41+
5. Do a final manual validation of those release artifacts. Install the plugin, Firefox extension, and Chrome extension, and verify basic functionality.
42+
6. On the Github page for your repo, click "Releases". (https://github.com/ChrisRegado/streamdeck-googlemeet/releases)
43+
7. Click "Draft a new release".
44+
8. Click the "Tag" button and select the tag you made in the previous step.
45+
9. Use the your tag name as the "Release title", and enter a description summarizing notable changes in this release.
46+
10. Select the "Set as a pre-release" checkbox near the bottom of the page.
47+
11. Click "Publish release".
48+
12. Our [release CI job](https://github.com/ChrisRegado/streamdeck-googlemeet/actions/workflows/release.yaml) should automatically start and attach our tag's artifacts to the GitHub Release. Wait for it to complete. If all goes well, in a minute or two you should see 3 attachments appear on the release: the `com.chrisregado.googlemeet.streamDeckPlugin` plugin, a zip of the Chrome extension, and an `.xpi` file for the Firefox extension.
49+
13. Edit the release, uncheck the "Set as a pre-release" checkbox at the bottom of the page, select the "Set as the latest release" checkbox, and click "Update release".

0 commit comments

Comments
 (0)