Skip to content

Commit 965a0e9

Browse files
committed
add github action for publishing
1 parent 940ebb2 commit 965a0e9

3 files changed

Lines changed: 323 additions & 0 deletions

File tree

.github/README.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Publish Workflow
2+
3+
A single GitHub Actions workflow that publishes both `flowise-embed` and `flowise-embed-react` to npm with matching version numbers.
4+
5+
## Flow
6+
7+
```
8+
workflow_dispatch (bump_type: patch / minor / major / exact version)
9+
|
10+
v
11+
reviewer approves (environment gate)
12+
|
13+
v
14+
flowise-embed: bump version -> install -> build -> npm publish -> commit + tag + push
15+
|
16+
v
17+
poll npm registry until new version is available
18+
|
19+
v
20+
flowise-embed-react: update dep + version -> install (updates yarn.lock) -> build -> npm publish -> commit + tag + push
21+
```
22+
23+
## Usage
24+
25+
### Publishing a new version
26+
27+
1. Go to **Actions** > **"Publish flowise-embed + flowise-embed-react"** > **Run workflow**
28+
2. Set `bump_type`:
29+
- `patch` — 3.1.2 -> 3.1.3
30+
- `minor` — 3.1.2 -> 3.2.0
31+
- `major` — 3.1.2 -> 4.0.0
32+
- Or an exact version like `3.2.0`
33+
3. Leave `recovery_version` empty
34+
4. Approve the environment gate when prompted
35+
5. Both packages publish to npm and both repos receive a version commit + git tag
36+
37+
### Recovery
38+
39+
If `flowise-embed` published successfully but `flowise-embed-react` failed:
40+
41+
1. Go to **Actions** > **"Publish flowise-embed + flowise-embed-react"** > **Run workflow**
42+
2. Leave `bump_type` at default (it won't be used)
43+
3. Set `recovery_version` to the version already published, e.g. `3.1.3`
44+
4. Approve the environment gate
45+
5. All `flowise-embed` steps are skipped — only `flowise-embed-react` is built and published
46+
47+
## Setup
48+
49+
### Secrets
50+
51+
Add to **FlowiseChatEmbed** repo settings:
52+
53+
| Secret | Description |
54+
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
55+
| `NPM_TOKEN` | npm **Automation** token with publish access to both `flowise-embed` and `flowise-embed-react`. Use the "Automation" type so it bypasses 2FA in CI. |
56+
| `PAT_GITHUB` | GitHub Personal Access Token with access to both `FlowiseChatEmbed` and `FlowiseEmbedReact` repos. |
57+
58+
#### PAT options
59+
60+
- **Classic PAT:** `repo` scope
61+
- **Fine-grained PAT (recommended):** Scope to the FlowiseAI org, select both repos, grant `Contents: Read and write`
62+
63+
### Environment
64+
65+
Create a `production` environment in **FlowiseChatEmbed** repo:
66+
67+
This gates every workflow run behind a human approval step.
68+
69+
## How it works
70+
71+
### Version bump
72+
73+
`npm version <bump_type> --no-git-tag-version` updates `package.json` without creating npm's default `v3.1.3` tag. The workflow controls the exact tag format: `flowise-embed@3.1.3`.
74+
75+
### Dependency update in FlowiseEmbedReact
76+
77+
The workflow sets `devDependencies.flowise-embed` to the exact new version using `npm pkg set`. This changes the specifier (e.g. from `"latest"` to `"3.1.3"`), which forces yarn to re-resolve from the registry and update `yarn.lock`. Both `package.json` and `yarn.lock` are committed back to the repo.
78+
79+
### npm registry propagation
80+
81+
After publishing `flowise-embed`, there's a short delay before the version is available on the registry. The workflow polls `npm view` every 10 seconds for up to 2 minutes before proceeding to the `flowise-embed-react` steps.
82+
83+
### Husky suppression
84+
85+
`HUSKY=0` is set during `yarn install` for FlowiseChatEmbed to prevent the `prepare` script (`husky install`) from failing in CI where there's no git hook context.
86+
87+
## What gets committed
88+
89+
| Repo | Files committed | Tag format |
90+
| ----------------- | --------------------------- | --------------------------- |
91+
| FlowiseChatEmbed | `package.json` | `flowise-embed@3.1.3` |
92+
| FlowiseEmbedReact | `package.json`, `yarn.lock` | `flowise-embed-react@3.1.3` |

.github/workflows/publish.yml

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
name: Publish flowise-embed + flowise-embed-react
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
bump_type:
7+
description: "Version bump: patch / minor / major — or exact version like 3.2.0"
8+
required: true
9+
default: patch
10+
recovery_version:
11+
description: "Recovery only: exact version if flowise-embed is already published but flowise-embed-react failed. Skips embed steps."
12+
required: false
13+
dry_run:
14+
description: "Test mode: builds and validates everything but does not publish to npm or push to git."
15+
type: boolean
16+
default: false
17+
18+
permissions:
19+
contents: write
20+
21+
jobs:
22+
publish:
23+
runs-on: ubuntu-latest
24+
environment: production
25+
steps:
26+
# ── Validate inputs (C-1, C-2, H-1) ──────────────────────────────────
27+
- name: Validate inputs
28+
env:
29+
BUMP_TYPE: ${{ inputs.bump_type }}
30+
RECOVERY_VERSION: ${{ inputs.recovery_version }}
31+
run: |
32+
SEMVER_RE='^[0-9]+\.[0-9]+\.[0-9]+$'
33+
BUMP_RE='^(patch|minor|major)$'
34+
if [ -n "$RECOVERY_VERSION" ]; then
35+
if ! echo "$RECOVERY_VERSION" | grep -Eq "$SEMVER_RE"; then
36+
echo "ERROR: recovery_version must be a valid semver (e.g. 3.2.0), got: $RECOVERY_VERSION"
37+
exit 1
38+
fi
39+
else
40+
if ! echo "$BUMP_TYPE" | grep -Eq "$BUMP_RE" && ! echo "$BUMP_TYPE" | grep -Eq "$SEMVER_RE"; then
41+
echo "ERROR: bump_type must be patch, minor, major, or a semver (e.g. 3.2.0), got: $BUMP_TYPE"
42+
exit 1
43+
fi
44+
fi
45+
46+
- name: Checkout FlowiseChatEmbed
47+
uses: actions/checkout@v4
48+
with:
49+
ref: main
50+
fetch-depth: 1
51+
path: flowise-embed
52+
token: ${{ secrets.PAT_GITHUB }}
53+
54+
- name: Checkout FlowiseEmbedReact
55+
uses: actions/checkout@v4
56+
with:
57+
repository: FlowiseAI/FlowiseEmbedReact
58+
fetch-depth: 1
59+
path: flowise-embed-react
60+
token: ${{ secrets.PAT_GITHUB }}
61+
62+
- name: Setup Node.js
63+
uses: actions/setup-node@v4
64+
with:
65+
node-version: "20"
66+
registry-url: "https://registry.npmjs.org"
67+
68+
- name: Configure git
69+
run: |
70+
git config --global user.name "github-actions[bot]"
71+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
72+
73+
- name: Resolve target version
74+
id: version
75+
working-directory: flowise-embed
76+
env:
77+
BUMP_TYPE: ${{ inputs.bump_type }}
78+
RECOVERY_VERSION: ${{ inputs.recovery_version }}
79+
run: |
80+
if [ -n "$RECOVERY_VERSION" ]; then
81+
echo "Recovery mode — skipping flowise-embed publish"
82+
echo "new_version=${RECOVERY_VERSION}" >> "$GITHUB_OUTPUT"
83+
echo "skip_embed=true" >> "$GITHUB_OUTPUT"
84+
else
85+
NEW=$(npm version "$BUMP_TYPE" --no-git-tag-version)
86+
NEW="${NEW#v}"
87+
if ! echo "$NEW" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
88+
echo "ERROR: npm version produced unexpected output: $NEW"
89+
exit 1
90+
fi
91+
echo "new_version=${NEW}" >> "$GITHUB_OUTPUT"
92+
echo "skip_embed=false" >> "$GITHUB_OUTPUT"
93+
fi
94+
95+
# ── flowise-embed ─────────────────────────────────────────────────────
96+
97+
- name: Install flowise-embed dependencies
98+
if: steps.version.outputs.skip_embed == 'false'
99+
working-directory: flowise-embed
100+
run: yarn install --frozen-lockfile
101+
env:
102+
HUSKY: "0"
103+
104+
- name: Build flowise-embed
105+
if: steps.version.outputs.skip_embed == 'false'
106+
working-directory: flowise-embed
107+
run: yarn build
108+
109+
- name: Publish flowise-embed to npm
110+
id: publish_embed
111+
if: steps.version.outputs.skip_embed == 'false'
112+
working-directory: flowise-embed
113+
run: |
114+
if [ "${{ inputs.dry_run }}" = "true" ]; then
115+
echo "DRY RUN — validating package with --dry-run"
116+
npm publish --access public --dry-run
117+
else
118+
npm publish --access public
119+
fi
120+
env:
121+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
122+
123+
- name: Commit and tag flowise-embed
124+
if: steps.version.outputs.skip_embed == 'false' && inputs.dry_run == 'false'
125+
working-directory: flowise-embed
126+
env:
127+
NEW_VERSION: ${{ steps.version.outputs.new_version }}
128+
run: |
129+
TAG="flowise-embed@${NEW_VERSION}"
130+
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "${TAG}"; then
131+
echo "Tag ${TAG} already exists on remote — skipping commit+tag"
132+
exit 0
133+
fi
134+
git add package.json
135+
git commit -m "${TAG}"
136+
git tag "${TAG}"
137+
git push origin HEAD "${TAG}"
138+
139+
# ── flowise-embed-react ───────────────────────────────────────────────
140+
141+
- name: Wait for flowise-embed on npm
142+
if: inputs.dry_run == false
143+
env:
144+
NEW_VERSION: ${{ steps.version.outputs.new_version }}
145+
run: |
146+
TARGET="flowise-embed@${NEW_VERSION}"
147+
for i in $(seq 1 12); do
148+
npm view "${TARGET}" version >/dev/null 2>&1 && echo "${TARGET} available" && exit 0
149+
echo "Attempt ${i}/12 — waiting 10s..."
150+
sleep 10
151+
done
152+
echo "ERROR: ${TARGET} not available after 2 min" && exit 1
153+
154+
- name: Update flowise-embed-react versions
155+
working-directory: flowise-embed-react
156+
env:
157+
NEW_VERSION: ${{ steps.version.outputs.new_version }}
158+
DRY_RUN: ${{ inputs.dry_run }}
159+
run: |
160+
if [ "$DRY_RUN" != "true" ]; then
161+
npm pkg set "devDependencies.flowise-embed=${NEW_VERSION}"
162+
else
163+
echo "DRY RUN — skipping devDependency update (version not on npm yet)"
164+
fi
165+
npm pkg set "version=${NEW_VERSION}"
166+
167+
- name: Install flowise-embed-react dependencies
168+
working-directory: flowise-embed-react
169+
run: |
170+
if [ "${{ inputs.dry_run }}" = "true" ]; then
171+
yarn install --frozen-lockfile
172+
else
173+
yarn install
174+
fi
175+
env:
176+
HUSKY: "0"
177+
178+
- name: Build flowise-embed-react
179+
working-directory: flowise-embed-react
180+
run: yarn build
181+
182+
- name: Publish flowise-embed-react to npm
183+
id: publish_react
184+
working-directory: flowise-embed-react
185+
run: |
186+
if [ "${{ inputs.dry_run }}" = "true" ]; then
187+
echo "DRY RUN — validating package with --dry-run"
188+
npm publish --access public --dry-run
189+
else
190+
npm publish --access public
191+
fi
192+
env:
193+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
194+
195+
- name: Commit and tag flowise-embed-react
196+
if: inputs.dry_run == false
197+
working-directory: flowise-embed-react
198+
env:
199+
NEW_VERSION: ${{ steps.version.outputs.new_version }}
200+
run: |
201+
TAG="flowise-embed-react@${NEW_VERSION}"
202+
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "${TAG}"; then
203+
echo "Tag ${TAG} already exists on remote — skipping commit+tag"
204+
exit 0
205+
fi
206+
git add package.json yarn.lock
207+
git commit -m "${TAG}"
208+
git tag "${TAG}"
209+
git push origin HEAD "${TAG}"
210+
211+
- name: Summary
212+
if: always()
213+
env:
214+
NEW_VERSION: ${{ steps.version.outputs.new_version }}
215+
SKIP_EMBED: ${{ steps.version.outputs.skip_embed }}
216+
EMBED_OUTCOME: ${{ steps.publish_embed.outcome }}
217+
REACT_OUTCOME: ${{ steps.publish_react.outcome }}
218+
DRY_RUN: ${{ inputs.dry_run }}
219+
run: |
220+
if [ "$DRY_RUN" = "true" ]; then
221+
echo "## Dry Run Results (nothing was published or pushed)" >> $GITHUB_STEP_SUMMARY
222+
else
223+
echo "## Publish Results" >> $GITHUB_STEP_SUMMARY
224+
fi
225+
if [ "$SKIP_EMBED" = "true" ]; then
226+
echo "- flowise-embed@${NEW_VERSION}: skipped (recovery mode)" >> $GITHUB_STEP_SUMMARY
227+
else
228+
echo "- flowise-embed@${NEW_VERSION}: ${EMBED_OUTCOME:-not reached}" >> $GITHUB_STEP_SUMMARY
229+
fi
230+
echo "- flowise-embed-react@${NEW_VERSION}: ${REACT_OUTCOME:-not reached}" >> $GITHUB_STEP_SUMMARY

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
src
2+
.github
23
rollup.config.js
34
tailwind.config.cjs
45
tsconfig.json

0 commit comments

Comments
 (0)