Skip to content

HagiCode-org/releases

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HagiCode Release

简体中文

HagiCode Release is the automation hub for turning built artifacts into distributable releases, container images, and publish records.

Product overview

This repository connects version discovery, GitHub Releases, and multi-registry Docker publishing so HagiCode builds can move from generated packages to public delivery.

What this repository handles

  • Monitor version sources and decide when a release pipeline should run
  • Publish application packages to GitHub Releases
  • Build and push multi-architecture Docker images
  • Synchronize publish results and release metadata across delivery channels
  • Ship the streamlined CLI baseline used inside the unified container runtime

Main areas

  • nukeBuild/ - release automation targets and shared build logic
  • .github/workflows/ - CI/CD pipelines for monitoring and publishing
  • docker_deployment/ - container build context, Dockerfiles, and entrypoint scripts
  • output/ - generated artifacts during local release work
  • ENVIRONMENT_VARIABLES.md - runtime and publishing configuration reference

Common release commands

./build.sh VersionMonitor
./build.sh GitHubRelease --ReleaseVersion "1.2.3"
./build.sh DockerRelease --ReleaseVersion "1.2.3" --DockerPlatform "all"

Use repository-specific credentials and registry settings from ENVIRONMENT_VARIABLES.md when preparing a real release.

Local container build and test

The repository now also ships a local docker compose workflow that reuses the existing Nuke-driven build-context generation instead of bypassing it:

cp .env.local.example .env.local
cp .env.secrets.local.example .env.secrets.local
./scripts/docker-local-build.sh
./scripts/docker-local-up.sh
./scripts/docker-local-test.sh
./scripts/docker-local-logs.sh
./scripts/docker-local-down.sh
  • docker-compose.local.yml uses the local image tag from HAGICODE_LOCAL_IMAGE and publishes the app to 127.0.0.1:5000 by default
  • Local persistence stays under ./.local/hagicode/data and ./.local/hagicode/saves
  • Keep plaintext local-only credentials in .env.secrets.local; the local scripts load it after .env.local, and build.sh/build.ps1 also load it automatically outside GitHub Actions
  • When AZURE_BLOB_SAS_URL is set, scripts/docker-local-build.sh downloads the requested version/platform package first; otherwise it reuses matching zip packages already present in output/download
  • Local image builds still need outbound access to Docker Hub, dot.net, GitHub, and npm unless your machine already has equivalent mirrors or caches
  • scripts/docker-local-test.sh waits for HTTP readiness and then smoke-tests the HagiScript-synced runtime baseline: hagiscript, claude, openspec, skills, opencode, codex, omniroute, pm2, pm2-runtime, and code-server inside the running container

Steam Linux desktop artifact verification

When a Linux desktop package bundles the optional portable payload under resources/extra/portable-fixed/current, keep the Steam startup contract aligned with the desktop bootstrap fix:

  • Steam launch of the packaged artifact must log that Steam Linux compatibility mode was enabled before the first window is created
  • The same packaged artifact launched directly from the CLI must log that compatibility mode was skipped and direct CLI launch keeps the default graphics path
  • If later startup diagnostics are captured, the copied startup-failure log should still begin with the [StartupCompatibility] context line so release triage can separate graphics-mode handling from unrelated failures

Trigger boundaries

Automatic publishing now has a single entry point:

  • ./build.sh VersionMonitor still discovers every unpublished Azure version, but it auto-selects only the newest unpublished version for the current run
  • GitHub Release automation starts only from repository_dispatch with event type version-monitor-release
  • Docker automation starts only from repository_dispatch with registry-specific event types (version-monitor-docker-aliyun, version-monitor-docker-azure, version-monitor-docker-dockerhub)
  • Older unpublished versions are reported as deferred backlog for later scheduled runs or manual handling

Manual reruns stay available, but they are explicit:

  • github-release-workflow.yml requires workflow_dispatch.version
  • Each docker-build-*.yml workflow requires workflow_dispatch.version and keeps optional platform / dry_run
  • Creating or reusing a Git tag no longer auto-starts GitHub Release or Docker workflows

Container CLI contract

The unified runtime image now builds from a clean debian:bookworm-slim base instead of inheriting the official node image user model. Node.js 22 is installed through an image-managed NVM layout under /usr/local/nvm, while npm-installed CLIs remain installed under /home/hagicode/.npm-global. During image build, the Node bootstrap layer clears NPM_CONFIG_PREFIX before nvm install; after the image switches to hagicode, npm config set prefix '/home/hagicode/.npm-global' restores the runtime/global-install contract for npm-delivered CLIs. The image then installs pinned @hagicode/hagiscript first and runs hagiscript npm-sync --managed-runtime /home/hagicode/.hagiscript/node-runtime --manifest /app/bootstrap/hagiscript-sync-manifest.json for the rest of the baked dependency baseline. The release-owned manifest selects the optional built-in agent CLIs claude-code, fission-openspec, opencode, and codex; HagiScript's internal catalog supplies mandatory skills, omniroute, and code-server; and the manifest keeps pm2@6.0.14 as a custom sync entry so pm2-runtime remains available. The managed HagiScript runtime is on PATH, so synced commands are available without runtime reinstall work in the entrypoint.

Only hagicode is supported as the non-root runtime user. When PUID and PGID are provided, container startup remaps that single user and reconciles ownership for /home/hagicode, its .claude state, and /app.

The unified runtime image bakes only the primary agent CLI baseline:

  • claude
  • opencode
  • codex

openspec remains in the image as the retained workflow tool for spec-driven changes, and skills remains bundled as the retained skill-management CLI. Both are synchronized through the same HagiScript catalog-backed baseline and documented separately from the primary agent CLI baseline so provider scope does not expand again by accident.

Provider CLIs such as copilot, codebuddy, and qodercli now follow the HagiCode UI-managed install path instead of shipping in the container by default. uipro is no longer part of the image because the bundled skills command replaces its previous shipped-runtime workflow.

Omniroute unified provider bootstrap

The release image now treats Omniroute as the unified local provider proxy for Claude, Codex/OpenAI, and OpenCode traffic inside the container.

  • Default local bind: 127.0.0.1:4060
  • Local management/runtime state: /app/data/omniroute
  • Shared process supervision: pm2-runtime
  • App readiness gate: /app/data/omniroute/runtime/hagicode.ready

Startup order is intentionally Omniroute-first:

  1. The entrypoint resolves the HagiCode app command and captures upstream provider credentials before any local reroute happens.
  2. The entrypoint normalizes Omniroute runtime paths and persisted secrets under /app/data/omniroute.
  3. The entrypoint exports the local Omniroute endpoint back into the runtime environment consumed by claude, codex, opencode, and HagiCode.
  4. pm2-runtime starts two managed processes: omniroute and hagicode-app.
  5. hagicode-app starts through wait-for-ready.sh, which blocks on the ready file until Omniroute bootstrap succeeds.
  6. The bootstrap helper logs into local Omniroute, upserts provider nodes/connections through the Omniroute HTTP API, writes bootstrap state, and releases the ready file.

Bootstrap is API-first and idempotent. The container does not mutate Omniroute SQLite files directly; it reuses persisted state and upserts only the providers that have the minimum upstream credentials configured.

After bootstrap, the container runtime rewires the main provider endpoints to local Omniroute URLs:

  • ANTHROPIC_URL points to the local Omniroute API base URL and ANTHROPIC_AUTH_TOKEN is replaced with the shared local key for Claude CLI traffic.
  • CODEX_BASE_URL / OPENAI_BASE_URL point to the local Omniroute API base URL and CODEX_API_KEY / OPENAI_API_KEY are replaced with the shared local key.
  • OPENCODE_BASE_URL / OPENCODE_API_BASE_URL point to the local Omniroute API base URL and OPENCODE_API_KEY is replaced with the shared local key.
  • HagiCode receives HAGICODE_OMNIROUTE_ENABLED=true, HAGICODE_OMNIROUTE_BASE_URL, HAGICODE_OMNIROUTE_API_BASE_URL, OmniRoute__Enabled, OmniRoute__BaseUrl, and OmniRoute__ApiBaseUrl.

Bundled Code Server runtime

The unified image now bakes a HagiScript catalog-backed code-server runtime into the same baseline so Builder can export browser-IDE defaults without asking operators to install extra packages after startup.

  • Builder full-custom mode exports VsCodeServer__* defaults directly into compose when you keep code-server enabled
  • Builder now exposes a shared EULA toggle that exports ACCEPT_EULA=Y only when operators explicitly opt in, and the entrypoint refuses startup without an accepted value
  • Dedicated host publishing remains opt-in, and the generated mapping binds to 127.0.0.1 by default for the first exposure step
  • Password auth requires CODE_SERVER_PASSWORD or CODE_SERVER_HASHED_PASSWORD; the entrypoint bridges those variables to the standard PASSWORD / HASHED_PASSWORD names before app startup
  • Both persistence roots are required in production deployments: hagicode_data:/app/data keeps system-scoped assets writable, and hagicode_saves:/app/saves keeps save-scoped runtime state writable
  • System-scoped assets still persist through hagicode_data:/app/data, and managed Code Server data stays under /app/data/code-server
  • Save-scoped HagiCode runtime state now persists through hagicode_saves:/app/saves, with the active save rooted at /app/saves/save0/...
  • The image and entrypoint prepare only /app/data and /app/saves; the application runtime still initializes /app/saves/save0/config and /app/saves/save0/data on demand
  • If you are upgrading from an older single-volume deployment, add a named volume or bind mount for /app/saves before replacing the container

Minimal mount layout:

volumes:
  - hagicode_data:/app/data
  - hagicode_saves:/app/saves

Startup SSH bootstrap

The release image now installs openssh-client and can import a mounted private key during startup when SSH access is explicitly required.

  • Set SSH_PRIVATE_KEY_PATH to a mounted private key file to enable bootstrap
  • Optionally set SSH_KNOWN_HOSTS_PATH to import a mounted known_hosts file
  • Optionally set SSH_STRICT_HOST_KEY_CHECKING to override the documented default of accept-new
  • Leave SSH_PRIVATE_KEY_PATH unset to skip SSH bootstrap entirely

At startup the entrypoint copies the mounted key into /home/hagicode/.ssh/imported_key, writes deterministic SSH config at /home/hagicode/.ssh/config, fixes ownership for the hagicode runtime user, and exports GIT_SSH_COMMAND so downstream git and ssh commands use the imported identity.

If SSH_PRIVATE_KEY_PATH is set but the file is missing, unreadable, or not a regular file, container startup fails fast with path-level diagnostics and never prints secret contents.

Ecosystem role

HagiCode Release takes outputs produced by repositories such as repos/hagicode-core and repos/hagicode-desktop, then publishes them to GitHub Releases, Azure ACR, Aliyun ACR, DockerHub, and related delivery channels.

About

Release automation hub for packaging HagiCode artifacts, publishing GitHub releases, and shipping multi-architecture images.

Topics

Resources

Stars

Watchers

Forks

Contributors