Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: pages

# Builds the @openhop/web bundle in fragment mode (no API server, flows in
# the URL hash) and deploys to GitHub Pages. Repo Settings → Pages must be
# set to "Source: GitHub Actions" for the deploy to succeed.
# the URL hash) and deploys to GitHub Pages. The workflow auto-enables Pages
# (with the GitHub Actions source) on first run via `enablement: true`, so
# fresh clones don't have to flip the toggle in repo Settings → Pages.

on:
push:
Expand Down Expand Up @@ -33,9 +34,13 @@ jobs:
- name: Build web (fragment mode)
run: npm run build -w @openhop/web
env:
VITE_BASE: /OpenHop/
# Repo is naorsabag/openhop (lowercase). The Pages site URL —
# https://naorsabag.github.io/openhop/ — is the asset base path.
VITE_BASE: /openhop/
VITE_FRAGMENT_MODE: "1"
- uses: actions/configure-pages@v5
with:
enablement: true
- uses: actions/upload-pages-artifact@v3
with:
path: packages/web/dist
Expand Down
83 changes: 83 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: publish

# Publishes @openhop/web and the openhop CLI to npm whenever the version in
# either package.json on master differs from what's already on the registry
# under the `beta` tag. Lets us ship a release just by merging a "chore: bump"
# PR — no manual `npm publish` step in someone's terminal.
#
# Web is published before CLI because the CLI's package.json depends on the
# web version. If only one bumped, only that one runs (the other is a no-op).

on:
push:
branches: [master]
paths:
- "packages/web/package.json"
- "packages/cli/package.json"
- "packages/cli/src/index.ts"
- "packages/server/package.json"
workflow_dispatch:

permissions:
contents: read
id-token: write

concurrency:
group: publish
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 22
registry-url: https://registry.npmjs.org/
cache: npm

- run: npm ci

- name: Resolve target versions
id: versions
run: |
web_version=$(node -p "require('./packages/web/package.json').version")
cli_version=$(node -p "require('./packages/cli/package.json').version")
echo "web=$web_version" >> "$GITHUB_OUTPUT"
echo "cli=$cli_version" >> "$GITHUB_OUTPUT"

- name: Check if @openhop/web@${{ steps.versions.outputs.web }} is already on npm
id: web_status
run: |
if npm view "@openhop/web@${{ steps.versions.outputs.web }}" version > /dev/null 2>&1; then
echo "publish=false" >> "$GITHUB_OUTPUT"
echo "::notice::@openhop/web@${{ steps.versions.outputs.web }} already on registry, skipping"
else
echo "publish=true" >> "$GITHUB_OUTPUT"
fi

- name: Check if openhop@${{ steps.versions.outputs.cli }} is already on npm
id: cli_status
run: |
if npm view "openhop@${{ steps.versions.outputs.cli }}" version > /dev/null 2>&1; then
echo "publish=false" >> "$GITHUB_OUTPUT"
echo "::notice::openhop@${{ steps.versions.outputs.cli }} already on registry, skipping"
else
echo "publish=true" >> "$GITHUB_OUTPUT"
fi

# Publish web first — the CLI's package.json depends on the web version.
- name: Publish @openhop/web
if: steps.web_status.outputs.publish == 'true'
working-directory: packages/web
run: npm publish --tag beta --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish openhop CLI
if: steps.cli_status.outputs.publish == 'true'
working-directory: packages/cli
run: npm publish --tag beta --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
3 changes: 1 addition & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
"test": "vitest run",
"test:cli-contract": "vitest run __tests__/contract.test.ts",
"build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --format=esm --external:commander --external:yaml --external:zod --external:@openhop/server --external:@openhop/web --external:fastify --external:@fastify/static --external:@fastify/http-proxy --outfile=dist/index.js --banner:js='#!/usr/bin/env node'",
"prepack": "rm -rf skills && cp -r ../../skills ./skills",
"prepare": "npm run build"
"prepack": "npm run build && rm -rf skills && cp -r ../../skills ./skills"
},
"dependencies": {
"@fastify/http-proxy": "^11.4.4",
Expand Down
6 changes: 3 additions & 3 deletions packages/web/__tests__/share-url.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ describe('share-url encode/decode', () => {
expect(decodeFragment('!!!~~~')).toBeNull()
})

it('buildShareUrl uses Vite BASE_URL so dev (/) and Pages (/OpenHop/) both work', () => {
it('buildShareUrl uses Vite BASE_URL so dev (/) and Pages (/openhop/) both work', () => {
const dev = buildShareUrl(SAMPLE_YAML, 'http://localhost:8788', '/')
expect(dev).toMatch(/^http:\/\/localhost:8788\/#[A-Za-z0-9_+\-$.]+$/)

const pages = buildShareUrl(SAMPLE_YAML, 'https://naorsabag.github.io', '/OpenHop/')
expect(pages).toMatch(/^https:\/\/naorsabag\.github\.io\/OpenHop\/#[A-Za-z0-9_+\-$.]+$/)
const pages = buildShareUrl(SAMPLE_YAML, 'https://naorsabag.github.io', '/openhop/')
expect(pages).toMatch(/^https:\/\/naorsabag\.github\.io\/openhop\/#[A-Za-z0-9_+\-$.]+$/)

// Hash content matches encodeFragment for both URLs (proves the BASE_URL
// only affects the path, never the encoded payload).
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/lib/share-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function decodeFragment(fragment: string): string | null {

/**
* Build the full sharable URL for a flow's YAML. Uses Vite's `BASE_URL` so the
* Pages deploy at `/OpenHop/` and dev at `/` both produce correct links.
* Pages deploy at `/openhop/` and dev at `/` both produce correct links.
*/
export function buildShareUrl(yamlText: string, origin: string, baseUrl: string): string {
const fragment = encodeFragment(yamlText)
Expand Down
Loading