Skip to content

Commit c17604a

Browse files
authored
feat: add comprehensive GitHub Action publish workflow (#3)
* feat: add comprehensive GitHub Action publish workflow - Add automated release workflow triggered by GitHub releases - Add build validation workflow for PR/push to main - Add manual version tag update workflow - Update package.json with additional build scripts - Add comprehensive publishing documentation Features: - Semantic versioning with multi-tag system (v1.0.0 + v1) - Automated building, testing, and validation - Quality gates before publishing - Manual override capability for version management - Follows GitHub Actions best practices This enables users to reference the action as: - @v1 (latest patches automatically) - @v1.0.0 (specific version locked) * fix: update pnpm version to 9 and add packageManager field - Update GitHub Actions workflows to use pnpm v9 instead of v8 - Add packageManager field to package.json for consistency - This should fix the check-dist workflow failure * fix: add explicit GITHUB_TOKEN permissions to workflows - Add 'contents: read' permission to check-dist workflow - Move 'contents: write' permission to workflow level for release and update-version workflows - Addresses GitHub Advanced Security feedback about explicit permissions * fix: improve pnpm setup in workflows - Match the exact pnpm setup pattern from working test.yml workflow - Add pnpm cache configuration for better performance - Change step name from 'Setup pnpm' to 'Install pnpm' - This should resolve the pnpm setup failures * fix: resolve pnpm version conflicts in workflows - Remove explicit version from pnpm/action-setup@v4 in all workflows - Let pnpm use the version specified in packageManager field ([email protected]) - This resolves the 'Multiple versions of pnpm specified' error - Also fixes the existing test.yml workflow that had the same conflict
1 parent 7a4d424 commit c17604a

File tree

6 files changed

+359
-3
lines changed

6 files changed

+359
-3
lines changed

.github/workflows/check-dist.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Check dist/
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
check-dist:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: '20'
24+
25+
- name: Install pnpm
26+
uses: pnpm/action-setup@v4
27+
28+
- name: Get pnpm store directory
29+
id: pnpm-cache
30+
shell: bash
31+
run: |
32+
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
33+
34+
- name: Setup pnpm cache
35+
uses: actions/cache@v4
36+
with:
37+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
38+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
39+
restore-keys: |
40+
${{ runner.os }}-pnpm-store-
41+
42+
- name: Install dependencies
43+
run: pnpm install --frozen-lockfile
44+
45+
- name: Build the action
46+
run: pnpm run build
47+
48+
- name: Compare the expected and actual dist/ directories
49+
run: |
50+
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
51+
echo "Detected uncommitted changes after build. See status below:"
52+
git diff --name-only
53+
git diff
54+
echo "Run 'pnpm run build' and commit the changes"
55+
exit 1
56+
fi
57+
id: diff
58+
59+
- name: Upload dist/ artifacts
60+
uses: actions/upload-artifact@v4
61+
if: failure() && steps.diff.conclusion == 'failure'
62+
with:
63+
name: dist
64+
path: dist/

.github/workflows/release.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
release:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: '20'
24+
25+
- name: Install pnpm
26+
uses: pnpm/action-setup@v4
27+
28+
- name: Get pnpm store directory
29+
id: pnpm-cache
30+
shell: bash
31+
run: |
32+
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
33+
34+
- name: Setup pnpm cache
35+
uses: actions/cache@v4
36+
with:
37+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
38+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
39+
restore-keys: |
40+
${{ runner.os }}-pnpm-store-
41+
42+
- name: Install dependencies
43+
run: pnpm install --frozen-lockfile
44+
45+
- name: Build the action
46+
run: pnpm run build
47+
48+
- name: Run tests
49+
run: pnpm run test
50+
env:
51+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
52+
53+
- name: Run type checking
54+
run: pnpm run typecheck
55+
56+
- name: Run linting
57+
run: pnpm run lint
58+
59+
- name: Extract version from tag
60+
id: version
61+
run: |
62+
TAG_NAME="${{ github.event.release.tag_name }}"
63+
VERSION=${TAG_NAME#v}
64+
MAJOR_VERSION=$(echo $VERSION | cut -d. -f1)
65+
echo "version=$VERSION" >> $GITHUB_OUTPUT
66+
echo "major_version=v$MAJOR_VERSION" >> $GITHUB_OUTPUT
67+
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
68+
69+
- name: Update package.json version
70+
run: |
71+
npm version ${{ steps.version.outputs.version }} --no-git-tag-version
72+
73+
- name: Rebuild with updated version
74+
run: pnpm run build
75+
76+
- name: Configure Git
77+
run: |
78+
git config user.name "github-actions[bot]"
79+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
80+
81+
- name: Commit built files
82+
run: |
83+
git add dist/ package.json
84+
git commit -m "Release ${{ steps.version.outputs.tag_name }}"
85+
86+
- name: Create or update major version tag
87+
run: |
88+
git tag -f ${{ steps.version.outputs.major_version }} ${{ steps.version.outputs.tag_name }}
89+
git push origin ${{ steps.version.outputs.major_version }} --force
90+
91+
- name: Push changes to release tag
92+
run: |
93+
git tag -f ${{ steps.version.outputs.tag_name }}
94+
git push origin ${{ steps.version.outputs.tag_name }} --force

.github/workflows/test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ jobs:
1717

1818
- name: Install pnpm
1919
uses: pnpm/action-setup@v4
20-
with:
21-
version: 9
2220

2321
- name: Get pnpm store directory
2422
id: pnpm-cache
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Update Version Tag
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
target:
7+
description: 'The tag or reference to use'
8+
required: true
9+
type: string
10+
major_version:
11+
description: 'The major version to update'
12+
required: true
13+
type: choice
14+
options:
15+
- v1
16+
- v2
17+
- v3
18+
- v4
19+
- v5
20+
21+
permissions:
22+
contents: write
23+
24+
jobs:
25+
update-version:
26+
runs-on: ubuntu-latest
27+
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 0
33+
34+
- name: Validate target reference
35+
run: |
36+
if ! git show-ref --verify --quiet refs/tags/${{ github.event.inputs.target }}; then
37+
echo "Error: Tag ${{ github.event.inputs.target }} does not exist"
38+
exit 1
39+
fi
40+
41+
- name: Configure Git
42+
run: |
43+
git config user.name "github-actions[bot]"
44+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
45+
46+
- name: Update major version tag
47+
run: |
48+
git tag -f ${{ github.event.inputs.major_version }} ${{ github.event.inputs.target }}
49+
git push origin ${{ github.event.inputs.major_version }} --force
50+
51+
- name: Summary
52+
run: |
53+
echo "✅ Successfully updated ${{ github.event.inputs.major_version }} to point to ${{ github.event.inputs.target }}"

PUBLISHING.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Publishing Workflow
2+
3+
This document describes how to publish new versions of the Only Robots GitHub Action.
4+
5+
## Overview
6+
7+
The action follows semantic versioning and uses a multi-tag system similar to other popular GitHub Actions:
8+
9+
- **Specific version tags**: `v1.0.0`, `v1.1.0`, `v1.1.1` (immutable, points to exact commit)
10+
- **Major version tags**: `v1`, `v2`, `v3` (mutable, points to latest release within major version)
11+
12+
## Publishing Process
13+
14+
### 1. Automated Publishing (Recommended)
15+
16+
The automated publishing workflow is triggered when you create a GitHub release:
17+
18+
1. **Create a GitHub Release**:
19+
- Go to the [Releases page](https://github.com/dcramer/action-onlyrobots/releases)
20+
- Click "Create a new release"
21+
- Tag version: `v1.0.0` (use semantic versioning)
22+
- Generate release notes or write them manually
23+
- Click "Publish release"
24+
25+
2. **Automatic Processing**:
26+
- The `release.yml` workflow will automatically:
27+
- Build the action
28+
- Run tests and linting
29+
- Update package.json version
30+
- Commit built files to the release tag
31+
- Update the major version tag (e.g., `v1``v1.0.0`)
32+
33+
### 2. Manual Version Tag Updates
34+
35+
If you need to manually update a major version tag to point to a different release:
36+
37+
1. Go to the [Actions tab](https://github.com/dcramer/action-onlyrobots/actions)
38+
2. Select "Update Version Tag" workflow
39+
3. Click "Run workflow"
40+
4. Enter:
41+
- **Target**: The existing tag to point to (e.g., `v1.0.1`)
42+
- **Major version**: The major version to update (e.g., `v1`)
43+
44+
## Workflow Files
45+
46+
### `.github/workflows/check-dist.yml`
47+
- Runs on push/PR to main
48+
- Ensures compiled `dist/` directory is up-to-date
49+
- Prevents merging code without proper build artifacts
50+
51+
### `.github/workflows/release.yml`
52+
- Runs when a GitHub release is published
53+
- Builds, tests, and publishes the action
54+
- Updates major version tags automatically
55+
56+
### `.github/workflows/update-version.yml`
57+
- Manual workflow for updating major version tags
58+
- Useful for hotfixes or corrections
59+
60+
## Pre-Release Checklist
61+
62+
Before creating a release:
63+
64+
1. **Ensure all changes are merged to main**
65+
2. **Run local validation**:
66+
```bash
67+
pnpm run validate
68+
```
69+
3. **Test the action locally**:
70+
```bash
71+
pnpm run test-pr
72+
```
73+
4. **Verify dist/ is up-to-date**:
74+
```bash
75+
pnpm run build
76+
git status # should show no changes in dist/
77+
```
78+
79+
## Version Strategy
80+
81+
### Major Versions (v1, v2, v3)
82+
- Breaking changes
83+
- New required inputs
84+
- Removed functionality
85+
- Major workflow changes
86+
87+
### Minor Versions (v1.1, v1.2)
88+
- New features
89+
- New optional inputs
90+
- Enhanced functionality
91+
- Non-breaking changes
92+
93+
### Patch Versions (v1.1.1, v1.1.2)
94+
- Bug fixes
95+
- Security patches
96+
- Documentation updates
97+
- Performance improvements
98+
99+
## User Consumption
100+
101+
Users can reference the action in multiple ways:
102+
103+
```yaml
104+
# Recommended: Use major version (gets latest patches automatically)
105+
- uses: dcramer/action-onlyrobots@v1
106+
107+
# Specific version (locked to exact release)
108+
- uses: dcramer/[email protected]
109+
110+
# Development version (not recommended for production)
111+
- uses: dcramer/action-onlyrobots@main
112+
```
113+
114+
## Troubleshooting
115+
116+
### Build Artifacts Out of Date
117+
If the `check-dist.yml` workflow fails:
118+
```bash
119+
pnpm run build
120+
git add dist/
121+
git commit -m "Update build artifacts"
122+
```
123+
124+
### Release Workflow Fails
125+
1. Check that `OPENAI_API_KEY` is set in repository secrets
126+
2. Verify the tag follows semantic versioning (e.g., `v1.0.0`)
127+
3. Ensure all tests pass locally with `pnpm run test`
128+
129+
### Major Version Tag Issues
130+
If a major version tag points to the wrong release:
131+
1. Use the "Update Version Tag" workflow
132+
2. Or manually update via CLI:
133+
```bash
134+
git tag -f v1 v1.0.1
135+
git push origin v1 --force
136+
```
137+
138+
## Security Notes
139+
140+
- Only repository maintainers can create releases
141+
- All builds are performed in GitHub Actions (not local machines)
142+
- Secrets are only accessible to the release workflow
143+
- Built artifacts are committed to release tags, not main branch

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
},
99
"scripts": {
1010
"build": "tsc",
11+
"build:clean": "rm -rf dist && pnpm run build",
1112
"start": "node dist/cli.js",
1213
"test-pr": "tsx src/test-cli.ts",
1314
"typecheck": "tsc --noEmit",
@@ -16,11 +17,14 @@
1617
"lint:fix": "pnpm run typecheck && biome lint --fix",
1718
"prepare": "simple-git-hooks",
1819
"test": "vitest run",
19-
"test:watch": "vitest"
20+
"test:watch": "vitest",
21+
"validate": "pnpm run typecheck && pnpm run lint && pnpm run test",
22+
"package": "pnpm run build:clean && pnpm run validate"
2023
},
2124
"keywords": [],
2225
"author": "David Cramer <[email protected]> (https://github.com/dcramer)",
2326
"license": "Apache-2.0",
27+
"packageManager": "[email protected]",
2428
"devDependencies": {
2529
"@biomejs/biome": "^2.1.1",
2630
"@types/node": "^24.0.14",

0 commit comments

Comments
 (0)