Skip to content

Commit 4a9c857

Browse files
authored
Add Github CI workflows (#5)
1 parent 048d81e commit 4a9c857

2 files changed

Lines changed: 241 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Formo SDK CI Check
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: read
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Setup Node
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: "22.14.0"
26+
cache: 'npm'
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Build SDK
32+
run: npm run build
33+
34+
test:
35+
runs-on: ubuntu-latest
36+
needs: build
37+
steps:
38+
- name: Checkout
39+
uses: actions/checkout@v4
40+
41+
- name: Setup Node
42+
uses: actions/setup-node@v4
43+
with:
44+
node-version: "22.14.0"
45+
cache: 'npm'
46+
47+
- name: Install dependencies
48+
run: npm ci
49+
50+
- name: Run tests
51+
run: npm test

.github/workflows/release.yml

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
name: Publish Package
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
id-token: write # Required for OIDC trusted publishing
10+
contents: write # Required for creating GitHub releases
11+
12+
jobs:
13+
publish:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0 # Fetch all history for changelog generation
20+
21+
- name: Verify tag is on main branch
22+
run: |
23+
# Check if the tag is reachable from main branch
24+
git fetch origin main
25+
if ! git merge-base --is-ancestor ${{ github.sha }} origin/main; then
26+
echo "❌ Error: This tag is not on the main branch"
27+
echo "Tags must be created on the main branch to trigger a release"
28+
echo "Current tag: ${{ github.ref_name }}"
29+
exit 1
30+
fi
31+
echo "✅ Tag is on main branch, proceeding with release"
32+
33+
- name: Setup Node
34+
uses: actions/setup-node@v4
35+
with:
36+
node-version: "22.14.0"
37+
cache: 'npm'
38+
39+
- name: Update npm for trusted publishing
40+
run: npm install -g npm@latest
41+
42+
- name: Install dependencies
43+
run: npm ci
44+
45+
- name: Extract version from tag
46+
id: version
47+
run: |
48+
VERSION=${GITHUB_REF#refs/tags/v}
49+
echo "version=$VERSION" >> $GITHUB_OUTPUT
50+
echo "Publishing version: $VERSION"
51+
52+
- name: Verify tag matches package.json version
53+
run: |
54+
TAG_VERSION=${{ steps.version.outputs.version }}
55+
PKG_VERSION=$(node -p "require('./package.json').version")
56+
57+
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
58+
echo "❌ Error: Tag version (v$TAG_VERSION) does not match package.json version ($PKG_VERSION)"
59+
echo "Please ensure package.json version is updated before creating the tag"
60+
exit 1
61+
fi
62+
63+
echo "✅ Version match confirmed: $TAG_VERSION"
64+
65+
- name: Build SDK
66+
run: npm run build
67+
68+
- name: Run tests
69+
run: npm test
70+
71+
- name: Generate release notes
72+
id: release_notes
73+
run: |
74+
# Get previous tag
75+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
76+
77+
# Get current date
78+
RELEASE_DATE=$(date +%Y-%m-%d)
79+
VERSION=${{ steps.version.outputs.version }}
80+
81+
# Generate changelog with PR links
82+
if [ -n "$PREV_TAG" ]; then
83+
echo "Generating changelog from $PREV_TAG to $GITHUB_REF_NAME"
84+
# Extract commits with PR numbers and format them
85+
# Use tab as delimiter to safely handle semicolons and special characters
86+
COMMITS=$(git log ${PREV_TAG}..HEAD --pretty=format:"%s %h" --no-merges)
87+
else
88+
echo "No previous tag found, using all commits"
89+
COMMITS=$(git log --pretty=format:"%s %h" --no-merges)
90+
fi
91+
92+
# Process commits and categorize them
93+
FEATURES=""
94+
FIXES=""
95+
OTHER=""
96+
97+
while IFS=$'\t' read -r message hash; do
98+
# Skip empty lines
99+
[ -z "$message" ] && continue
100+
101+
# Extract PR number if exists
102+
if [[ $message =~ \(#([0-9]+)\) ]]; then
103+
PR_NUM="${BASH_REMATCH[1]}"
104+
# Remove the (#PR_NUM) from message to avoid duplication (handles with or without space)
105+
CLEAN_MESSAGE=$(echo "$message" | sed -E 's/ ?\(#[0-9]+\)//')
106+
PR_LINK="[#$PR_NUM](https://github.com/${{ github.repository }}/pull/$PR_NUM)"
107+
COMMIT_LINK="[$hash](https://github.com/${{ github.repository }}/commit/$hash)"
108+
ITEM="$CLEAN_MESSAGE ($PR_LINK) ($COMMIT_LINK)"
109+
else
110+
COMMIT_LINK="[$hash](https://github.com/${{ github.repository }}/commit/$hash)"
111+
ITEM="$message ($COMMIT_LINK)"
112+
fi
113+
114+
# Categorize by prefix and strip conventional commit prefix
115+
if [[ $message =~ ^feat(\([^\)]+\))?: ]]; then
116+
# Strip "feat:" or "feat(scope):" from the beginning of ITEM
117+
STRIPPED_ITEM=$(echo "$ITEM" | sed -E 's/^feat(\([^)]+\))?: //')
118+
FEATURES="${FEATURES}- ${STRIPPED_ITEM}
119+
"
120+
elif [[ $message =~ ^fix(\([^\)]+\))?: ]]; then
121+
# Strip "fix:" or "fix(scope):" from the beginning of ITEM
122+
STRIPPED_ITEM=$(echo "$ITEM" | sed -E 's/^fix(\([^)]+\))?: //')
123+
FIXES="${FIXES}- ${STRIPPED_ITEM}
124+
"
125+
else
126+
OTHER="${OTHER}- ${ITEM}
127+
"
128+
fi
129+
done <<< "$COMMITS"
130+
131+
# Create release notes
132+
cat > release_notes.md <<EOF
133+
$VERSION ($RELEASE_DATE)
134+
EOF
135+
136+
# Add Features section if exists
137+
if [ -n "$FEATURES" ]; then
138+
cat >> release_notes.md <<EOF
139+
140+
## Features
141+
142+
$FEATURES
143+
EOF
144+
fi
145+
146+
# Add Fixes section if exists
147+
if [ -n "$FIXES" ]; then
148+
cat >> release_notes.md <<EOF
149+
150+
## Bug Fixes
151+
152+
$FIXES
153+
EOF
154+
fi
155+
156+
# Add Other changes if exists and no features/fixes
157+
if [ -z "$FEATURES" ] && [ -z "$FIXES" ] && [ -n "$OTHER" ]; then
158+
cat >> release_notes.md <<EOF
159+
160+
## Changes
161+
162+
$OTHER
163+
EOF
164+
fi
165+
166+
# Add npm package link
167+
cat >> release_notes.md <<EOF
168+
169+
## Install
170+
171+
\`\`\`bash
172+
npm install @formo/analytics-node@$VERSION
173+
\`\`\`
174+
175+
[@formo/analytics-node $VERSION npm package](https://www.npmjs.com/package/@formo/analytics-node/v/$VERSION)
176+
EOF
177+
178+
- name: Publish to npm
179+
run: npm publish --provenance
180+
# Explicitly use --provenance flag for clarity
181+
# OIDC trusted publishing (id-token: write) enables automatic provenance generation
182+
183+
- name: Create GitHub Release
184+
uses: softprops/action-gh-release@v1
185+
with:
186+
body_path: release_notes.md
187+
draft: false
188+
prerelease: false
189+
env:
190+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)