diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 02023d966..75968dca1 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -13,9 +13,34 @@ on: workflow_dispatch: inputs: paseo_version: - description: "Paseo npm version to build for validation. Defaults to latest." + description: "Paseo version to build. Required when publish is true." required: false default: "" + publish: + description: "Publish the image to GHCR. Manual publishes require paseo_version." + required: false + default: "false" + type: choice + options: + - "false" + - "true" + source_build: + description: "Build from the checked-out source tree instead of npm." + required: false + default: "auto" + type: choice + options: + - auto + - "false" + - "true" + publish_latest: + description: "Also publish ghcr.io/getpaseo/paseo:latest. Ignored for prereleases." + required: false + default: "false" + type: choice + options: + - "false" + - "true" concurrency: group: docker-${{ github.workflow }}-${{ github.ref }} @@ -41,6 +66,9 @@ jobs: - id: values env: INPUT_PASEO_VERSION: ${{ inputs.paseo_version }} + INPUT_PUBLISH: ${{ inputs.publish }} + INPUT_PUBLISH_LATEST: ${{ inputs.publish_latest }} + INPUT_SOURCE_BUILD: ${{ inputs.source_build }} REPO_OWNER: ${{ github.repository_owner }} REF_NAME: ${{ github.ref_name }} run: | @@ -51,6 +79,7 @@ jobs: install_version="${INPUT_PASEO_VERSION:-latest}" publish=false source_build=false + publish_latest=false prerelease=false if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then @@ -59,14 +88,49 @@ jobs: if [[ "${REF_NAME}" == *-* ]]; then prerelease=true source_build=true + else + publish_latest=true + fi + elif [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then + if [[ "${INPUT_PUBLISH:-false}" == "true" ]]; then + if [[ -z "${INPUT_PASEO_VERSION}" || "${INPUT_PASEO_VERSION}" == "latest" ]]; then + echo "::error::paseo_version is required for manual Docker publishes." + exit 1 + fi + publish=true + fi + + if [[ "${install_version}" == *-* ]]; then + prerelease=true + fi + + case "${INPUT_SOURCE_BUILD:-auto}" in + true) + source_build=true + ;; + false) + source_build=false + ;; + auto) + if [[ "${prerelease}" == "true" ]]; then + source_build=true + fi + ;; + *) + echo "::error::source_build must be auto, true, or false." + exit 1 + ;; + esac + + if [[ "${INPUT_PUBLISH_LATEST:-false}" == "true" && "${prerelease}" != "true" ]]; then + publish_latest=true fi fi check_tag="${image}:check-${GITHUB_SHA::12}" - if [[ "${prerelease}" == "true" ]]; then - publish_tags="${image}:${install_version}" - else - publish_tags="${image}:${install_version}"$'\n'"${image}:latest" + publish_tags="${image}:${install_version}" + if [[ "${publish_latest}" == "true" ]]; then + publish_tags="${publish_tags}"$'\n'"${image}:latest" fi { diff --git a/docs/docker.md b/docs/docker.md index c10b67c56..160a2e9fd 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -208,6 +208,22 @@ non-publishing check. Stable `vX.Y.Z` tag pushes publish publish only the exact prerelease tag, such as `ghcr.io/getpaseo/paseo:0.1.102-beta.1`, and do not update `latest`. +To replace a Docker image in place without rebuilding desktop, APK, or EAS +mobile release artifacts, dispatch the Docker workflow manually instead of +pushing a `v*` release tag: + +```bash +gh workflow run docker.yml \ + --ref main \ + -f paseo_version=0.1.102-beta.1 \ + -f publish=true \ + -f source_build=auto +``` + +Manual Docker publishes require an explicit `paseo_version`. Prerelease +versions build from the checked-out source tree by default and publish only the +exact prerelease image tag. + The published image is multi-arch for `linux/amd64` and `linux/arm64`. ## Troubleshooting diff --git a/docs/release.md b/docs/release.md index 5203feea3..f91f0d837 100644 --- a/docs/release.md +++ b/docs/release.md @@ -273,9 +273,31 @@ The GitHub Release body is populated automatically by the `Release Notes Sync` w **Do not rely on `workflow_dispatch` for tagged code fixes.** The `workflow_dispatch` trigger runs the workflow file from the default branch but checks out the code at the tag ref (`ref: ${{ inputs.tag }}`). That means fixes committed to `main` won't change the tagged source tree being built. `workflow_dispatch` only helps when the fix lives in the workflow file itself. -To retry a failed workflow, **always push a retry tag** on the commit you want to build. Reusing the same tag name is expected: move it with `git tag -f ...` and push it with `--force` so the workflow rebuilds the commit you actually want. +For Docker-only retries, **do not push or force-push a `v*` release tag**. +`v*` tag pushes rebuild desktop assets, the Android APK, Docker, release notes, +and EAS mobile release builds. Use the Docker workflow dispatch instead: -Prefer a tag push over `workflow_dispatch` whenever you are rebuilding release code or release assets. +```bash +gh workflow run docker.yml \ + --ref main \ + -f paseo_version=X.Y.Z-beta.N \ + -f publish=true \ + -f source_build=auto +``` + +This replaces `ghcr.io/getpaseo/paseo:X.Y.Z-beta.N` in place without touching +desktop, APK, or EAS release builders. The Docker exception is safe because the +dispatch runs from `--ref main` and uses the explicit `paseo_version`; it does +not check out or move the `v*` release tag. + +To retry a failed non-Docker release workflow, push a retry tag on the commit +you want to build. Reusing the same tag name is expected: move it with +`git tag -f ...` and push it with `--force` so the workflow rebuilds the commit +you actually want. + +Prefer a tag push over `workflow_dispatch` when rebuilding desktop or APK +release assets. Prefer Docker workflow dispatch when rebuilding only the Docker +image. The retry tag patterns below still work and remain the supported way to rebuild specific release targets: