Skip to content

Commit 19ce5d1

Browse files
authored
Merge pull request #5 from RocketChat/ci/build-and-release-workflows
Add CI and release GitHub Actions workflows
2 parents 76a3f9e + d48f41b commit 19ce5d1

5 files changed

Lines changed: 173 additions & 34 deletions

File tree

.github/workflows/ci.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
build:
11+
name: Lint, typecheck & package
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: 22
22+
cache: npm
23+
cache-dependency-path: external-chat/package-lock.json
24+
25+
- name: Install dependencies
26+
working-directory: external-chat
27+
run: npm ci
28+
29+
- name: Lint
30+
working-directory: external-chat
31+
run: npm run lint
32+
33+
- name: Typecheck
34+
working-directory: external-chat
35+
run: npx tsc --noEmit
36+
37+
- name: Build & package the zip (no version bump)
38+
run: |
39+
make package
40+
VERSION=$(node -p "require('./external-chat/package.json').version")
41+
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
42+
43+
- name: Upload plugin zip artifact
44+
uses: actions/upload-artifact@v4
45+
with:
46+
name: external-chat-v${{ env.VERSION }}
47+
path: external-chat-v${{ env.VERSION }}.zip
48+
if-no-files-found: error

.github/workflows/release.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Release
2+
3+
# Manually-triggered release: reads the current version from package.json,
4+
# builds the plugin zip, then creates a matching git tag and GitHub release
5+
# with the zip attached as an asset. Bump the version (e.g. `make bump`) and
6+
# commit it before running this.
7+
on:
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: write # required to create tags and releases
12+
13+
jobs:
14+
release:
15+
name: Tag & release
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: 22
26+
cache: npm
27+
cache-dependency-path: external-chat/package-lock.json
28+
29+
- name: Install dependencies
30+
working-directory: external-chat
31+
run: npm ci
32+
33+
- name: Read version from package.json
34+
run: echo "VERSION=$(node -p "require('./external-chat/package.json').version")" >> "$GITHUB_ENV"
35+
36+
- name: Ensure this version is not already released
37+
env:
38+
GH_TOKEN: ${{ github.token }}
39+
run: |
40+
if gh release view "v$VERSION" >/dev/null 2>&1; then
41+
echo "::error::Release v$VERSION already exists. Bump the version in external-chat/package.json first."
42+
exit 1
43+
fi
44+
45+
- name: Build & package the zip
46+
run: make package
47+
48+
- name: Create tag & GitHub release with the zip asset
49+
env:
50+
GH_TOKEN: ${{ github.token }}
51+
run: |
52+
gh release create "v$VERSION" \
53+
"external-chat-v$VERSION.zip" \
54+
--target "$GITHUB_SHA" \
55+
--title "external-chat v$VERSION" \
56+
--generate-notes

Makefile

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,33 @@ DIST := $(PROJECT)/dist
66
WEBAPP3 := $(ROOT)/webapp3
77
PLUGIN_DIR := $(WEBAPP3)/branding/plugins/external-chat
88

9-
.PHONY: all bump build deploy package clean
9+
.PHONY: all release bump build deploy package clean
1010

11-
all: package
11+
# Default: a full release (bumps the version, then packages).
12+
all: release
1213

13-
# 1. Bump the minor version in external-chat/package.json (no git commit/tag).
14-
# Done first so the build embeds the new version in its logs.
14+
# Full release: bump the minor version first, then build & package with it.
15+
# Uses sub-makes so the bump always completes before the build starts.
16+
release:
17+
$(MAKE) bump
18+
$(MAKE) package
19+
20+
# Bump the minor version in external-chat/package.json (no git commit/tag).
1521
bump:
1622
cd $(PROJECT) && npm version minor --no-git-tag-version
1723

18-
# 2. Build the external-chat project.
19-
build: bump
24+
# Build the external-chat project.
25+
build:
2026
cd $(PROJECT) && npm run build
2127

22-
# 3. Copy the freshly built dist into webapp3/branding/plugins/external-chat.
28+
# Copy the freshly built dist into webapp3/branding/plugins/external-chat.
2329
deploy: build
2430
rm -rf $(PLUGIN_DIR)
2531
mkdir -p $(PLUGIN_DIR)
2632
cp -R $(DIST)/. $(PLUGIN_DIR)/
2733

28-
# 4. Zip the webapp3 bundle into external-chat-v<version>.zip, named from package.json.
34+
# Zip the webapp3 bundle into external-chat-v<version>.zip using the CURRENT
35+
# version from package.json (no bump). This is what CI calls.
2936
package: deploy
3037
@VERSION=$$(node -p "require('$(PROJECT)/package.json').version"); \
3138
cd $(ROOT) && zip -r -q external-chat-v$$VERSION.zip webapp3 -x '*.DS_Store'; \

README.md

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -187,33 +187,60 @@ plugin at runtime (`plugin: external-chat loaded v<version>`).
187187

188188
## Building & packaging with the Makefile
189189

190-
Run all `make` commands from the **repository root**. The pipeline bumps the
191-
version, builds the plugin, copies it into the branding bundle, and produces a
192-
versioned zip.
190+
Run all `make` commands from the **repository root**.
193191

194192
```bash
195-
make # same as `make package` — runs the full pipeline
193+
make # full release: bump the minor version, build, then package
194+
make package # build & package using the CURRENT version (no bump)
196195
```
197196

198197
### Targets
199198

200-
| Target | What it does |
201-
| --- | --- |
202-
| `make bump` | Bumps the **minor** version in `external-chat/package.json` (`npm version minor --no-git-tag-version` — no git commit or tag). |
203-
| `make build` | Runs `bump`, then `npm run build` so the new version is embedded in the bundle. |
204-
| `make deploy` | Runs `build`, then copies `external-chat/dist/` into `webapp3/branding/plugins/external-chat/`. |
205-
| `make package` | Runs `deploy`, then zips the `webapp3/` folder into `external-chat-v<version>.zip` at the repo root. |
206-
| `make all` | Alias for `make package` (the default target). |
207-
| `make clean` | Removes `external-chat/dist/` and the deployed plugin folder. |
208-
209-
Dependency chain: `package → deploy → build → bump`.
199+
| Target | What it does | Bumps version? |
200+
| --- | --- | --- |
201+
| `make release` | Bumps the version, then runs `package`. ||
202+
| `make all` | Alias for `make release` (the default target). ||
203+
| `make bump` | Bumps the **minor** version in `external-chat/package.json` (`npm version minor --no-git-tag-version` — no git commit or tag). ||
204+
| `make build` | Runs `npm run build`. ||
205+
| `make deploy` | Runs `build`, then copies `external-chat/dist/` into `webapp3/branding/plugins/external-chat/`. ||
206+
| `make package` | Runs `deploy`, then zips the `webapp3/` folder into `external-chat-v<version>.zip` at the repo root, using the current `package.json` version. ||
207+
| `make clean` | Removes `external-chat/dist/` and the deployed plugin folder. ||
208+
209+
Dependency chains: `release → bump → package → deploy → build`. Only `release`,
210+
`all`, and `bump` change the version — `build`/`deploy`/`package` use the current
211+
one, so **CI and one-off packaging never bump** (CI runs `make package`).
210212

211213
### Output
212214

213215
`make` produces `external-chat-v<version>.zip` in the repo root, where `<version>`
214-
is the freshly bumped value from `package.json` (e.g. `external-chat-v1.4.0.zip`).
215-
The zip contains the full `webapp3/` branding bundle, ready to upload.
216+
is the value in `package.json` (e.g. `external-chat-v1.4.0.zip`) — freshly bumped
217+
by `make`/`make release`, or unchanged by `make package`. The zip contains the
218+
full `webapp3/` branding bundle, ready to upload.
219+
220+
## Continuous integration
221+
222+
`.github/workflows/ci.yml` runs on pushes to `main`, on pull requests, and on
223+
manual dispatch. It installs dependencies (`npm ci`), then runs **lint**,
224+
**typecheck** (`tsc --noEmit`), and **`make package`** (build + zip, **no version
225+
bump**). The resulting `external-chat-v<version>.zip` is uploaded as a downloadable
226+
workflow artifact named `external-chat-v<version>`.
227+
228+
## Releasing
229+
230+
`.github/workflows/release.yml` is a **manually triggered** workflow
231+
(Actions → *Release**Run workflow*). It reads the current version from
232+
`external-chat/package.json`, builds the zip (`make package`, no bump), then
233+
creates a `v<version>` git tag and a GitHub release with
234+
`external-chat-v<version>.zip` attached as an asset. Release notes are
235+
auto-generated from the changes since the previous release.
236+
237+
Typical flow:
238+
239+
```bash
240+
make bump # 1. bump the minor version in package.json
241+
git commit -am "release" # 2. commit the bump (and push)
242+
# 3. run the "Release" workflow from the Actions tab
243+
```
216244

217-
> ⚠️ **Every `make` (or `make build`/`deploy`/`package`) bumps the minor version**,
218-
> because `build` depends on `bump`. To build *without* bumping, run
219-
> `cd external-chat && npm run build` directly and copy `dist/` yourself.
245+
If a release for the current version already exists, the workflow fails with a
246+
reminder to bump first (it never overwrites an existing tag/release).

external-chat/src/index.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { ButtonRPCPayload, registerPlugin } from '@pexip/plugin-api'
1+
import { registerPlugin } from '@pexip/plugin-api'
2+
import type { ButtonRPCPayload } from '@pexip/plugin-api'
23
import { version } from '../package.json'
34

4-
function fireParentMessage(action: string, data?: Record<string, unknown>) {
5+
function fireParentMessage(action: string, data?: Record<string, unknown>): void {
56
action = `pexip:plugin:external-chat/${action}`;
67

78
console.log(`plugin: external-chat sending message to parent: ${action}`, data);
@@ -26,8 +27,8 @@ const buttonConfig: ButtonRPCPayload['toolbar']['add'] = {
2627

2728
const button = await plugin.ui.addButton(buttonConfig);
2829

29-
function renderButton() {
30-
button.update({
30+
function renderButton(): void {
31+
void button.update({
3132
...buttonConfig,
3233
isActive: isChatAtive,
3334
tooltip: isChatAtive ? 'Close Chat' : 'Open Chat',
@@ -37,12 +38,12 @@ function renderButton() {
3738
});
3839
}
3940

40-
function setChatActive(isActive: boolean) {
41+
function setChatActive(isActive: boolean): void {
4142
isChatAtive = isActive;
4243
renderButton();
4344
}
4445

45-
function setBadgeVisible(isVisible: boolean) {
46+
function setBadgeVisible(isVisible: boolean): void {
4647
isBadgeVisible = isVisible;
4748
renderButton();
4849
}
@@ -51,7 +52,7 @@ function setBadgeVisible(isVisible: boolean) {
5152
type DialOutParams = Parameters<typeof plugin.conference.dialOut>[0];
5253

5354
// Dial out to a destination on behalf of the top window and report the outcome back.
54-
async function dialOut(params: DialOutParams) {
55+
async function dialOut(params: DialOutParams): Promise<void> {
5556
try {
5657
const participant = await plugin.conference.dialOut(params);
5758
fireParentMessage('dial-out-success', {

0 commit comments

Comments
 (0)