Skip to content

chore(ci): publish the image under ghcr.io/zoolutions - #98

Merged
mhenrixon merged 1 commit into
dashfrom
chore/ghcr-zoolutions-org
Aug 10, 2026
Merged

chore(ci): publish the image under ghcr.io/zoolutions#98
mhenrixon merged 1 commit into
dashfrom
chore/ghcr-zoolutions-org

Conversation

@mhenrixon

@mhenrixon mhenrixon commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

The repo moved to the zoolutions org; a workflow's GITHUB_TOKEN can only write packages in its own owner namespace, so pushing to the mhenrixon user package fails with permission_denied: The requested installation does not exist — which is why the v1.0.0.2 image never published.

Points docker-publish.yml, script/release-dash and the docs at ghcr.io/zoolutions/kamal-proxy. After merging, v1.0.0.3 will be cut from dash (same Go code as the never-published v1.0.0.2 — that tag's workflow still pushes to the old org, so it can never publish) and the dash gem's defaults move in lockstep (zoolutions/kamal#109).

Note: after the first publish, make the new ghcr package public — kamal deploys and integration tests pull anonymously.


Summary by cubic

Switch Docker image publishing to ghcr.io/zoolutions/kamal-proxy to fix CI permission errors after the org move and unblock new releases. Updates the release script and docs to match.

  • Bug Fixes

    • Point .github/workflows/docker-publish.yml tags to ghcr.io/zoolutions/kamal-proxy (latest and versioned).
    • Update script/release-dash messages to the new namespace.
    • Refresh docs and guides from ghcr.io/mhenrixon/kamal-proxy to ghcr.io/zoolutions/kamal-proxy.
  • Migration

    • After the first publish, set ghcr.io/zoolutions/kamal-proxy to public (anonymous pulls).
    • Cut v1.0.0.3 from dash and update the gem’s MINIMUM_VERSION to that tag.

Written for commit 1940868. Summary will update on new commits.

Review in cubic

The repo moved to the zoolutions org for enterprise Actions minutes, and
a workflow's GITHUB_TOKEN can only write packages in its own owner
namespace - pushing to the mhenrixon user package now fails with
"permission_denied: The requested installation does not exist" (which is
why v1.0.0.2 never published). Point the publish workflow, the release
script and the docs at ghcr.io/zoolutions/kamal-proxy.

The dash gem's repository defaults move in lockstep (zoolutions/kamal#109).
@mhenrixon
mhenrixon enabled auto-merge (squash) August 10, 2026 09:57

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

mhenrixon added a commit to zoolutions/kamal that referenced this pull request Aug 10, 2026
…0.0.3

The repos moved to the zoolutions org (enterprise Actions minutes), and a
workflow's GITHUB_TOKEN can only write packages in its own owner
namespace - so the proxy's publish workflow could no longer push to the
mhenrixon user package, which is why the v1.0.0.2 image never appeared.
The image now publishes as ghcr.io/zoolutions/kamal-proxy
(zoolutions/kamal-proxy#98); this points the gem's repository defaults,
docs, tests, integration harness, toolkit and the dash CLI image
workflow at the new org.

MINIMUM_VERSION moves to v1.0.0.3: the v1.0.0.2 tag predates the
workflow fix, so its tag-triggered build pushes to the old org and can
never publish - v1.0.0.3 is the same Go code cut from dash after the
fix. Manifest regenerated for it (flag surface unchanged).

Refs #108
@mhenrixon
mhenrixon merged commit 249b394 into dash Aug 10, 2026
3 checks passed
@mhenrixon
mhenrixon deleted the chore/ghcr-zoolutions-org branch August 10, 2026 10:05
mhenrixon added a commit to zoolutions/kamal that referenced this pull request Aug 10, 2026
…rt transfer and per-zone DNS providers (#109)

* chore(proxy): require kamal-proxy v1.0.0.2

Bump MINIMUM_VERSION to the proxy release carrying the dynamic redirect
map, deny lists, cert store import/export and per-zone DNS-01 providers
(kamal-proxy#86-#90), and regenerate the flag manifest from that tag's
binary. The four new deploy flags the manifest gains are wired up in the
commits that follow.

Refs #108

* feat(proxy): redirects_source, deny lists and per-zone DNS-01 providers

deploy.yml keys for three of the v1.0.0.2 proxy capabilities, so none of
them needs the run.flags escape hatch:

* proxy/redirects_source {source, interval}: the dynamic redirect map
  (--redirects-source/--redirects-interval). Edge disposition - it
  answers at the loadbalancer like ssl_domains and canonical_host - and
  composes with static redirects (map first, rules on a miss). The
  validator mirrors the ssl_domains source shape and refuses an interval
  below the proxy's own 10s minimum at config time.

* proxy/deny_ips + proxy/deny_user_agents (--deny-ip/--deny-user-agent),
  edge beside allow_ips/rate_limit. IP entries get the allow_ips
  validation; UA patterns are shape-checked only (Go RE2 and Ruby Onigmo
  disagree at the edges - same reasoning as redirects/rewrites). The
  root-healthcheck-path guard, the trusted_proxies no-effect check and
  the cannot-identify-clients warning now count deny_ips, since deny
  rules key on the same client address.

* proxy/run/acme/dns_provider hash form: zone=provider entries pinning
  each zone to the DNS host that serves it, `default` covering the rest,
  emitted as repeatable --acme-dns-provider flags with the bare default
  last. The string form keeps meaning what it always has.

Refs #108

* feat(proxy): kamal proxy export_certs / import_certs

CLI for the v1.0.0.2 certificate store transfer: export the estate for
disaster recovery, import from a Traefik acme.json or restore an
exported archive - the Traefik-migration path that must work before the
first proxy boot.

Both commands target the host that owns TLS: the loadbalancer host when
load balancing, else the primary host. The command surface is shared by
the proxy and loadbalancer builders (Commands::Proxy::CertTransfer);
each supplies its own container, config volume and one-off image, so a
loadbalancer sharing a proxy host transfers through the shared
kamal-proxy volume.

Transport picks the safe path per state: a running container exports
through its RPC socket under the proxy's certificate write lock, a
stopped one through a one-off offline container. Archives leave via the
apps-config bind mount - the one path that is both a host and a
container path - and imports stream through stdin into the one-off
container, because a bind-mounted source would need host permissions the
container user cannot be guaranteed to have, and the store must be
written as the image's own user. Import refuses a running container
(offline-only in the proxy) except for --verify, which only reads the
archive; contradictory flag combinations fail before anything uploads,
mirroring kamal-proxy's own flag groups.

Refs #108

* chore(proxy): move the proxy image to ghcr.io/zoolutions, require v1.0.0.3

The repos moved to the zoolutions org (enterprise Actions minutes), and a
workflow's GITHUB_TOKEN can only write packages in its own owner
namespace - so the proxy's publish workflow could no longer push to the
mhenrixon user package, which is why the v1.0.0.2 image never appeared.
The image now publishes as ghcr.io/zoolutions/kamal-proxy
(zoolutions/kamal-proxy#98); this points the gem's repository defaults,
docs, tests, integration harness, toolkit and the dash CLI image
workflow at the new org.

MINIMUM_VERSION moves to v1.0.0.3: the v1.0.0.2 tag predates the
workflow fix, so its tag-triggered build pushes to the old org and can
never publish - v1.0.0.3 is the same Go code cut from dash after the
fix. Manifest regenerated for it (flag surface unchanged).

Refs #108

* fix(integration): fail setup.sh at a broken seed pull

Without set -e a failed proxy-image seed (pull/tag/push into
registry:4443) exits 0 - the script ends with rm -f - and the miss
surfaces much later, deep inside an unrelated deploy, as "manifest
unknown". Exactly the failure-at-a-distance the seeding comment warns
about; now the setup step fails on the line that broke.

* fix(proxy): harden cert transfer per review; finish org sweep

Review findings from PR #109 (cubic):

* import: an apostrophe in --resolver could end the single-quoted sh -c
  payload and run arbitrary commands on the target host - build the
  payload with Base#shell, which escapes embedded quotes.
* export: take the deploy lock (a concurrent deploy could reboot the
  proxy mid-export and tear the offline read), and remove the archive in
  an ensure so a failed download does not leave private keys on the host.
* import: move upload! inside the ensure's reach so a failed or partial
  upload cannot leave certificate material behind either.
* acme: a non-string, blank or whitespace zone key would emit an
  --acme-dns-provider entry no zone ever matches - reject it at config
  time.
* finish the ghcr org sweep: test/integration/main_test.rb and the
  testing-rules examples spell the image with regex-escaped dots, which
  the plain-string replace could not match.

* fix(integration): surface setup.sh stderr in the harness failure message

The harness's docker_compose captures stdout and discards the stderred
block, so a docker daemon error in the seed (they all print to stderr)
left three CI runs failing blind after "gems installed". exec 2>&1 puts
everything setup.sh does onto the one stream the failure message carries.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant