chore: bootstrap hermes-ui skeleton from 0.6.29 snapshot
Import the client, server, skills, tests, and build scripts as the starting point for the rebuild, then trim the surfaces this project does not ship: Electron desktop packaging, the marketing website, and the ESP32 firmware tree. CI keeps the web build, e2e, lockfile, release, and Docker workflows. Rename the package and CLI entry points to hermes-ui, drop the prepare hook so npm ci no longer triggers a build, and drop the removed tsconfig and nodemon references. Rewrite AGENTS.md, ARCHITECTURE.md, DEVELOPMENT.md, and the READMEs so the documented package map and hard rules match this repository. reference_code/ is ignored: it is a read-only snapshot, not an input to the build.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- base
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: build-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm ci --ignore-scripts
|
||||
npm rebuild node-pty
|
||||
|
||||
- name: Check repository harness
|
||||
run: npm run harness:check
|
||||
|
||||
- name: Test with coverage
|
||||
run: npm run test:coverage
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
@@ -0,0 +1,61 @@
|
||||
name: Build and Push Docker Image to Docker Hub
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: docker-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/hermes-web-ui:latest
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/hermes-web-ui:${{ github.sha }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/hermes-web-ui:${{ github.event.release.tag_name || github.ref_name }}
|
||||
|
||||
keep-release-out-of-latest:
|
||||
name: Keep release out of GitHub latest
|
||||
if: always() && github.event_name == 'release'
|
||||
needs: build-and-push
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Mark release as not latest
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ github.event.release.tag_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --latest=false
|
||||
@@ -0,0 +1,45 @@
|
||||
name: NPM Lockfile Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- package.json
|
||||
- package-lock.json
|
||||
- .github/workflows/npm-lockfile-check.yml
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- base
|
||||
paths:
|
||||
- package.json
|
||||
- package-lock.json
|
||||
- .github/workflows/npm-lockfile-check.yml
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: npm-lockfile-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: npm ci --ignore-scripts
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
|
||||
- name: Verify package-lock.json is in sync
|
||||
run: npm ci --ignore-scripts
|
||||
@@ -0,0 +1,52 @@
|
||||
name: Playwright
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: playwright-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm ci --ignore-scripts
|
||||
npm rebuild node-pty
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: npx playwright install --with-deps chromium
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: npm run test:e2e
|
||||
|
||||
- name: Upload Playwright report
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-report
|
||||
path: |
|
||||
playwright-report/
|
||||
test-results/
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,108 @@
|
||||
name: Publish Web UI Artifact to Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Existing release tag to attach the Web UI artifact to"
|
||||
required: true
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: webui-release-${{ github.event.release.tag_name || github.event.inputs.tag || github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
webui:
|
||||
name: Web UI
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.release.tag_name || github.event.inputs.tag }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
cache-dependency-path: package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm ci --ignore-scripts
|
||||
npm rebuild node-pty
|
||||
|
||||
- name: Build Web UI
|
||||
run: npm run build
|
||||
|
||||
- name: Keep production dependencies only
|
||||
run: npm prune --omit=dev --no-audit --no-fund
|
||||
|
||||
- name: Package Web UI
|
||||
id: package
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="$(node -p "require('./package.json').version")"
|
||||
asset="hermes-web-ui-${version}.tar.gz"
|
||||
manifest="hermes-web-ui-${version}.json"
|
||||
mkdir -p release/webui /tmp/hermes-web-ui-package/webui
|
||||
|
||||
cp package.json package-lock.json /tmp/hermes-web-ui-package/webui/
|
||||
cp -R bin dist node_modules /tmp/hermes-web-ui-package/webui/
|
||||
|
||||
tar -czf "release/webui/${asset}" -C /tmp/hermes-web-ui-package webui
|
||||
sha256="$(shasum -a 256 "release/webui/${asset}" | awk '{print $1}')"
|
||||
size="$(stat -c%s "release/webui/${asset}")"
|
||||
printf '%s %s\n' "$sha256" "$asset" > "release/webui/${asset}.sha256"
|
||||
|
||||
node - <<'NODE' "$version" "$asset" "$sha256" "$size" "release/webui/${manifest}"
|
||||
const { writeFileSync } = require('node:fs')
|
||||
const [version, asset, sha256, size, manifest] = process.argv.slice(2)
|
||||
writeFileSync(manifest, JSON.stringify({
|
||||
schema: 1,
|
||||
webUiVersion: version,
|
||||
createdAt: new Date().toISOString(),
|
||||
asset: {
|
||||
name: asset,
|
||||
sha256,
|
||||
size: Number(size),
|
||||
},
|
||||
}, null, 2) + '\n')
|
||||
NODE
|
||||
|
||||
echo "asset=${asset}" >> "$GITHUB_OUTPUT"
|
||||
echo "manifest=${manifest}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload Web UI artifact to release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.event.release.tag_name || github.event.inputs.tag }}
|
||||
make_latest: false
|
||||
fail_on_unmatched_files: true
|
||||
files: |
|
||||
release/webui/${{ steps.package.outputs.asset }}
|
||||
release/webui/${{ steps.package.outputs.asset }}.sha256
|
||||
release/webui/${{ steps.package.outputs.manifest }}
|
||||
|
||||
keep-release-out-of-latest:
|
||||
name: Keep release out of GitHub latest
|
||||
if: always() && github.event_name == 'release'
|
||||
needs: webui
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Mark release as not latest
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ github.event.release.tag_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --latest=false
|
||||
Reference in New Issue
Block a user