Skip to content

Commit d72f5f2

Browse files
author
Lasim
committed
feat(gateway): add release workflow and update changelog for automated releases
1 parent 4fd03f2 commit d72f5f2

File tree

6 files changed

+312
-2
lines changed

6 files changed

+312
-2
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: Gateway Release PR
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
type:
6+
type: choice
7+
description: Choose release type
8+
options:
9+
- patch
10+
- minor
11+
- major
12+
default: patch
13+
beta:
14+
type: boolean
15+
description: Prerelease
16+
default: false
17+
18+
permissions:
19+
contents: write
20+
pull-requests: write
21+
issues: write
22+
23+
jobs:
24+
releaseIt:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 0
30+
# Use the app token for checkout as well
31+
token: ${{ secrets.APP_INSTALLATION_TOKEN }}
32+
- name: git config
33+
run: |
34+
git config user.name "${GITHUB_ACTOR}"
35+
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
36+
- name: Setup node
37+
uses: actions/setup-node@v4
38+
with:
39+
node-version: 20
40+
cache: npm
41+
42+
# Install dependencies from root (same as backend pipeline)
43+
- name: Install dependencies
44+
run: |
45+
npm ci || {
46+
echo "npm ci failed, trying clean install..."
47+
npm install --no-optional
48+
}
49+
50+
- name: Gateway Build Test
51+
working-directory: services/gateway
52+
run: npm run build
53+
54+
- name: Gateway Unit Tests
55+
working-directory: services/gateway
56+
run: npm run test:unit || echo "Tests not implemented yet, skipping"
57+
58+
- name: Gateway Lint
59+
working-directory: services/gateway
60+
run: npm run lint || echo "Linting not configured yet, skipping"
61+
62+
- name: Check for console.log in gateway
63+
working-directory: services/gateway
64+
run: npm run check:no-console || echo "Console check not configured yet, skipping"
65+
66+
- name: Prepare release
67+
working-directory: services/gateway
68+
env:
69+
GITHUB_TOKEN: ${{ secrets.APP_INSTALLATION_TOKEN }}
70+
TYPE_ARG: ${{ fromJSON('{"patch":"patch", "minor":"minor", "major":"major"}')[github.event.inputs.type] }}
71+
BETA_ARG: ${{ github.event.inputs.beta == 'true' && '--preRelease=beta' || '' }}
72+
run: npm run release -- $TYPE_ARG --ci --verbose --no-git.push --no-git.commit --no-git.tag --no-github --no-npm $BETA_ARG
73+
- name: Update version.ts file
74+
working-directory: services/gateway
75+
run: |
76+
node scripts/update-version.js || echo "Version update script not found, skipping"
77+
if [ -f src/config/version.ts ]; then
78+
git add src/config/version.ts
79+
fi
80+
- name: get-npm-version
81+
id: package-version
82+
uses: martinbeentjes/npm-get-version-action@main
83+
with:
84+
path: services/gateway
85+
- name: Extract release notes
86+
id: extract-release-notes
87+
run: |
88+
# Get the current version from the package.json in the current working directory
89+
VERSION=$(cat package.json | grep '"version"' | cut -d'"' -f4)
90+
echo "Extracting release notes for version $VERSION"
91+
92+
# Extract the changelog section for this version
93+
if [ -f CHANGELOG.md ]; then
94+
# Look for the version header and extract content until the next version or end of file
95+
RELEASE_NOTES=$(awk -v version="$VERSION" '
96+
BEGIN { found=0; content="" }
97+
/^##? [0-9]+\.[0-9]+\.[0-9]+/ {
98+
if (found) exit
99+
if ($0 ~ version) { found=1; next }
100+
}
101+
found && /^##? [0-9]+\.[0-9]+\.[0-9]+/ { exit }
102+
found { content = content $0 "\n" }
103+
END { print content }
104+
' CHANGELOG.md)
105+
106+
# Remove empty lines
107+
CLEAN_NOTES=$(echo "$RELEASE_NOTES" | sed '/^$/d')
108+
109+
# Save to output
110+
echo "release_notes<<EOF" >> $GITHUB_OUTPUT
111+
echo "$CLEAN_NOTES" >> $GITHUB_OUTPUT
112+
echo "EOF" >> $GITHUB_OUTPUT
113+
114+
echo "Release notes extracted:"
115+
echo "$CLEAN_NOTES"
116+
else
117+
echo "No CHANGELOG.md found"
118+
echo "release_notes=" >> $GITHUB_OUTPUT
119+
fi
120+
working-directory: services/gateway
121+
- name: Create pull request
122+
uses: peter-evans/create-pull-request@v7
123+
id: cpr
124+
with:
125+
# This is the key change - use the app token
126+
token: ${{ secrets.APP_INSTALLATION_TOKEN }}
127+
branch: gateway-release
128+
delete-branch: true
129+
commit-message: 'chore(gateway): release v${{ steps.package-version.outputs.current-version}}'
130+
title: '[Gateway Release] v${{ steps.package-version.outputs.current-version}}'
131+
body: |
132+
## Gateway Release v${{ steps.package-version.outputs.current-version}}
133+
134+
This PR prepares a new gateway release.
135+
136+
When merged, this will:
137+
1. Create a release tag
138+
2. Build and publish the npm package to @deploystack/gateway
139+
140+
The npm package will be available at:
141+
- `@deploystack/gateway@latest`
142+
- `@deploystack/gateway@v${{ steps.package-version.outputs.current-version}}`
143+
144+
### Installation
145+
```bash
146+
npm install -g @deploystack/gateway@${{ steps.package-version.outputs.current-version}}
147+
```
148+
149+
## Release notes:
150+
${{ steps.extract-release-notes.outputs.release_notes }}
151+
labels: |
152+
gateway
153+
release
154+
automated pr
155+
draft: false
156+
- name: Show PR link
157+
if: ${{ steps.cpr.outputs.pull-request-url }}
158+
run: |
159+
echo "Gateway Release v${{ steps.package-version.outputs.current-version}}' pull request - ${{ steps.cpr.outputs.pull-request-url }}"
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: Gateway Release
2+
on:
3+
pull_request:
4+
types: [closed]
5+
branches:
6+
- main
7+
paths:
8+
- 'services/gateway/**'
9+
10+
permissions:
11+
contents: write
12+
pull-requests: write
13+
14+
jobs:
15+
release:
16+
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'gateway') && contains(github.event.pull_request.labels.*.name, 'release')
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
# Use the app token for checkout as well
23+
token: ${{ secrets.APP_INSTALLATION_TOKEN }}
24+
25+
- name: git config
26+
run: |
27+
git config user.name "${GITHUB_ACTOR}"
28+
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
29+
30+
- name: Setup node
31+
uses: actions/setup-node@v4
32+
with:
33+
node-version: 20
34+
cache: npm
35+
registry-url: 'https://registry.npmjs.org'
36+
37+
# Install dependencies at root level for workspaces
38+
- name: Install dependencies
39+
run: npm ci
40+
41+
# Now run release-it with the APP_INSTALLATION_TOKEN
42+
- name: Prepare release
43+
working-directory: services/gateway
44+
env:
45+
GITHUB_TOKEN: ${{ secrets.APP_INSTALLATION_TOKEN }}
46+
run: npm run release -- --ci --verbose --no-git.requireCleanWorkingDir --no-npm
47+
48+
# Get the version after release-it has run
49+
- name: Get version
50+
id: package-version
51+
uses: martinbeentjes/npm-get-version-action@main
52+
with:
53+
path: services/gateway
54+
55+
# Build the gateway
56+
- name: Build gateway
57+
working-directory: services/gateway
58+
run: |
59+
npm run build
60+
61+
# Publish to npm
62+
- name: Publish to npm
63+
working-directory: services/gateway
64+
env:
65+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
66+
run: |
67+
# Publish the package to npm
68+
npm publish --access public
69+
70+
- name: Release summary
71+
run: |
72+
echo "# Gateway Release v${{ steps.package-version.outputs.current-version }} Published! 🚀" >> $GITHUB_STEP_SUMMARY
73+
echo "" >> $GITHUB_STEP_SUMMARY
74+
echo "The gateway has been successfully released and published to npm." >> $GITHUB_STEP_SUMMARY
75+
echo "" >> $GITHUB_STEP_SUMMARY
76+
echo "### Installation" >> $GITHUB_STEP_SUMMARY
77+
echo "" >> $GITHUB_STEP_SUMMARY
78+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
79+
echo "npm install -g @deploystack/gateway@${{ steps.package-version.outputs.current-version }}" >> $GITHUB_STEP_SUMMARY
80+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
81+
echo "" >> $GITHUB_STEP_SUMMARY
82+
echo "### Package Details" >> $GITHUB_STEP_SUMMARY
83+
echo "" >> $GITHUB_STEP_SUMMARY
84+
echo "- **Package**: [@deploystack/gateway](https://www.npmjs.com/package/@deploystack/gateway)" >> $GITHUB_STEP_SUMMARY
85+
echo "- **Version**: v${{ steps.package-version.outputs.current-version }}" >> $GITHUB_STEP_SUMMARY
86+
echo "- **Release Tag**: [v${{ steps.package-version.outputs.current-version }}](https://github.com/${{ github.repository }}/releases/tag/v${{ steps.package-version.outputs.current-version }})" >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ services/backend/tests/e2e/test-data/*.db
7070
._*.png
7171
._*.webp
7272
._*.jpg
73+
._*.yml
74+
._*.yaml
7375
cookies.txt
7476
cookiejar.txt
7577
cookie.txt

services/gateway/.release-it.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module.exports = {
2+
"git": {
3+
"commitMessage": "chore(gateway): release v${version}",
4+
"tagName": "gateway-v${version}",
5+
"tagAnnotation": "Gateway Release ${version}",
6+
"addUntrackedFiles": "false"
7+
},
8+
"github": {
9+
"release": true,
10+
"releaseName": "Gateway v${version}"
11+
},
12+
"npm": {
13+
"publish": false // We handle npm publishing separately in the workflow
14+
},
15+
"hooks": {
16+
"before:init": ["echo 'Preparing gateway release...'"],
17+
"after:bump": "npm run build",
18+
"after:release": "echo 'Gateway ${version} released!'"
19+
},
20+
"plugins": {
21+
"@release-it/conventional-changelog": {
22+
"preset": {
23+
"name": "angular"
24+
},
25+
"infile": "CHANGELOG.md",
26+
"ignoreRecommendedBump": true,
27+
"path": "services/gateway",
28+
"writerOpts": {
29+
"commitsFilter": ["feat", "fix", "perf", "revert"],
30+
"transform": function(commit, context) {
31+
// Only include commits with gateway scope or no scope
32+
const scopes = commit.scope ? commit.scope.split(',') : [];
33+
if (commit.scope && !scopes.includes('gateway') && !scopes.includes('all')) {
34+
return;
35+
}
36+
37+
// Create a new commit object to avoid modifying immutable object
38+
const newCommit = Object.assign({}, commit);
39+
40+
// Ensure commit hash is available for link text
41+
if (newCommit.hash) {
42+
newCommit.shortHash = newCommit.hash.substring(0, 7);
43+
}
44+
45+
return newCommit;
46+
},
47+
"commitPartial": "* {{subject}} ([{{shortHash}}](https://github.com/deploystackio/deploystack/commit/{{hash}}))\n"
48+
}
49+
}
50+
}
51+
};

services/gateway/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Changelog
2+
3+
All notable changes to the DeployStack Gateway will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

services/gateway/package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
"build": "tsc",
1111
"start": "node dist/index.js",
1212
"dev": "ts-node-dev --respawn src/index.ts",
13-
"link": "npm run build && npm link"
13+
"link": "npm run build && npm link",
14+
"release": "release-it --config=.release-it.js",
15+
"lint": "echo 'Linting not configured yet'",
16+
"test:unit": "echo 'Tests not implemented yet'",
17+
"check:no-console": "echo 'Console check not configured yet'"
1418
},
1519
"keywords": [
1620
"mcp",
@@ -26,6 +30,8 @@
2630
"devDependencies": {
2731
"@types/node": "^24.1.0",
2832
"ts-node-dev": "^2.0.0",
29-
"typescript": "^5.3.3"
33+
"typescript": "^5.3.3",
34+
"@release-it/conventional-changelog": "^10.0.1",
35+
"release-it": "^19.0.4"
3036
}
3137
}

0 commit comments

Comments
 (0)