The Docker Hub mirror workflow used `secrets.DOCKERHUB_USERNAME != ''`
directly inside step `if:` conditions and step-level `env:`
expressions. GitHub's expression parser now rejects that with
`Unrecognized named-value: 'secrets'` — the `secrets` context is only
allowed in a narrow set of positions (mostly `with:` inputs and step
`env:` values, not inside `if:` expressions).
Route the check through a dedicated detection step whose `env:` reads
the secrets (the one permitted way to surface them) and writes a
plain boolean to step outputs. Every downstream conditional then
guards on `steps.dockerhub.outputs.enabled == 'true'` instead.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Every image published to `ghcr.io/caorushizi/mediago` now also gets
pushed to `docker.io/caorushizi/mediago` under the same tags, so users
can `docker pull caorushizi/mediago:3.5.0` without setting up GHCR
auth.
- New `DOCKERHUB_IMAGE` env var pinning the Docker Hub slug.
- New `Login to Docker Hub` step guarded by
`secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != ''`
so forks without Docker Hub credentials can still build + push to
GHCR without failing the login.
- New `Resolve image targets` step that composes the metadata-action
`images:` list at runtime — only adds the Docker Hub target when
both secrets are present. Without this, metadata-action would keep
emitting Docker Hub tags that build-push-action would then 401 on.
- Build Summary shows both `docker pull` hints when Docker Hub is
enabled.
Setup (one-time, in repo Settings → Secrets and variables → Actions):
- `DOCKERHUB_USERNAME`: Docker Hub account name
- `DOCKERHUB_TOKEN`: PAT from https://hub.docker.com/settings/security
with Read+Write scope on caorushizi/mediago
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When a released image has to be re-cut (e.g. the broken 3.5.0 that
shipped with the stale per-downloader flags), there was no clean way
to re-publish under the same tag from the workflow — only a fresh
git tag push would trigger a build.
Extend `workflow_dispatch` with two inputs:
- `tag` — image tag to publish under (e.g. `3.5.0` to overwrite
the existing one, or `3.5.0-fix.1` for a side-by-side).
Empty value falls back to the pre-existing
`dev-<run_id>` behaviour.
- `push_latest` — when rebuilding a stable release manually, optionally
re-stamp the `latest` tag at the same time.
`docker/metadata-action` already emits the standard OCI labels,
including `org.opencontainers.image.revision` sourced from `github.sha`.
That field alone is enough to tell two same-tag builds apart via
`docker inspect` — no Dockerfile changes needed, no manually-computed
build args. Summary step now reads version / commit from metadata-action's
own outputs (`steps.meta.outputs.version`) and `github.sha`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Node.js 20 reached EOL in April 2026. Upgrade build Node.js
version to 24.14.0 LTS across all CI workflows.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rewrite Dockerfile as 3-stage build (Node builder → Go builder → runtime)
- Use --platform=$BUILDPLATFORM for native Node/Go compilation (no QEMU)
- Cross-compile Go binary via GOOS/GOARCH for target architecture
- Add --platform flag to download-deps.ts for target-specific deps
- Map Docker TARGETARCH to Node arch naming (amd64 → linux-x64)
- Flatten deps directory structure in runtime image
- Rewrite build-server.yml to push to ghcr.io with docker/metadata-action
- Single job multi-arch build (linux/amd64 + linux/arm64) via QEMU
- Update .dockerignore to exclude electron, docs, build artifacts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge the standalone mediago-player binary into mediago-core. The core
now serves the player UI at /player/ via go:embed, and provides video
listing/streaming endpoints. Video root reuses the existing download
directory (local-dir) so no separate flag is needed.
Changes:
- Add internal/video package to core (handler, service, types)
- Embed player-ui assets via //go:embed in assets/embed.go
- Add SPA handler for /player/ path
- Register /api/v1/videos and /videos/* routes in core router
- core:build now builds player-ui before Go compilation
- Remove apps/player/ entirely (Go app, scripts, configs)
- Remove VideoServer from Electron, derive playerUrl from coreUrl
- Remove player binary management from server app
- Update CI workflow to remove player go.sum cache path
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add shell option for Windows in player's runCommand to fix
"spawn pnpm ENOENT" error (Windows needs shell:true to find .cmd)
- Add deps:download step to CI workflow so third-party tools
(ffmpeg, BBDown, etc.) are available during packaging
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The build was failing because:
- macOS runners don't have Go pre-installed (exit code 127)
- Ubuntu/Windows runners lack the swag tool (spawn swag ENOENT)
Add setup-go action and swag installation step before building.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Docker configuration to resolve node-pty native module conflicts
- Create docker/Dockerfile for production builds
- Create docker/Dockerfile.dev for development with hot reload
- Add docker-compose.yml for easy development setup
- Include system dependencies (python3, make, g++, libicu-dev) for native modules
- Update package.json with dev:docker and build:docker commands
- Move .dockerignore to root directory for proper build context
- Remove electron rebuild scripts as Docker handles native module compilation
- Enable mixed development: webapi in container, electron on host
Usage:
- pnpm dev:docker # Start webapi in Docker container
- pnpm -F electron dev # Start electron locally in parallel
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Rename apps with more descriptive names:
• main → electron (Electron main process)
• renderer → frontend (React UI for both Electron and web)
• backend → webapi (Koa.js API server)
- Remove tools/scripts custom build logic:
• Replace custom zx scripts with native Turbo commands
• Update dev command to use Turbo filters for plugin/mobile builds
• Migrate web-release build to use Turbo pipeline
• Remove tools/scripts directory entirely
- Update comprehensive README documentation for each app:
• apps/electron/README.md - Desktop application lifecycle and system integration
• apps/frontend/README.md - React UI shared between Electron and web
• apps/webapi/README.md - Standalone API server with Docker support
- Update all configuration references:
• package.json: Update all Turbo filter commands
• biome.json: Remove tools/scripts path references
• pnpm-workspace.yaml: Remove tools/* workspace
• CLAUDE.md: Update architecture documentation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>