Skip to content

Latest patch builds and requests#263

Merged
ericmj merged 14 commits into
mainfrom
latest-patch-builds-and-requests
Jun 16, 2026
Merged

Latest patch builds and requests#263
ericmj merged 14 commits into
mainfrom
latest-patch-builds-and-requests

Conversation

@ericmj

@ericmj ericmj commented Jun 12, 2026

Copy link
Copy Markdown
Member
  • Only automatically trigger builds for the latest patch per Erlang and Elixir version family.
    Docker images were built for every Erlang patch release crossed with every Elixir build, producing tens of thousands of redundant tags per new OS version. Collapse the expected set to the newest ref per Erlang major.minor line and the newest Elixir build per minor and OTP major, and restrict the Elixir expansion to that latest-patch Erlang set so historical or manually built Erlang tags no longer fan out.

  • Add request build page
    Authenticated hex.pm users pick an image kind, OS, base image version, and the exact Erlang (and Elixir) version from dropdowns derived from the real OTP refs and Elixir builds, so submitted values are valid by construction. Versions load through a small read-through cache since listing OTP refs takes over a dozen GitHub requests. Recent requests are listed with their reconciliation state.

ericmj added 7 commits June 12, 2026 16:57
Docker images were built for every Erlang patch release crossed with
every Elixir build, producing tens of thousands of redundant tags per
new OS version. Collapse the expected set to the newest ref per Erlang
major.minor line and the newest Elixir build per minor and OTP major,
and restrict the Elixir expansion to that latest-patch Erlang set so
historical or manually built Erlang tags no longer fan out.

Also expose the build rules as a public validation API for the
upcoming user-requested builds feature.
Authenticate users against hexpm's OAuth 2.0 provider with the
authorization code + PKCE flow, mirroring the hexdocs integration.
Tokens and the hex.pm username live in the (now encrypted) session
cookie; access tokens are refreshed five minutes before expiry and the
session lasts 30 days. Only identity is requested (api:read scope).

This prepares for user-requested Docker builds, which will require a
logged-in hex.pm user.
Authenticated users can request builds of specific patch versions the
latest-patch policy skips. Requests are one-time (pinned to the current
base image), validated against the existing build rules, and capped at
ten builds per user per hour. Every request is recorded in the
build_requests table.

The DockerChecker reconciles pending requests each cycle: Elixir images
build FROM the Erlang image and failed jobs are not retried, so the
Erlang base is enqueued first and the Elixir job follows once the base
tag exists. Requests complete when all target tags exist and expire
when their os_version rotates out or after 14 days.
Authenticated hex.pm users pick an image kind, OS, base image version,
and the exact Erlang (and Elixir) version from dropdowns derived from
the real OTP refs and Elixir builds, so submitted values are valid by
construction. Versions load through a small read-through cache since
listing OTP refs takes over a dozen GitHub requests. Recent requests
are listed with their reconciliation state.
@ericmj ericmj marked this pull request as ready for review June 16, 2026 12:06
ericmj added 7 commits June 16, 2026 14:14
The recent requests list showed only the current user's requests; show
every user's requests instead, with a username column and the same
pager the other views use. Add Bob.BuildRequests.recent/2 and count/0
for pagination, and prune finished requests older than 90 days from the
periodic queue maintenance sweep alongside the job history.
A request was marked completed as soon as the per-arch tags existed,
before the multi-arch manifest users actually pull was assembled. Track
the manifest instead: once both arch tags exist, enqueue the manifest
job from the reconciliation (in addition to manifest/0) and only
complete the request once hexpm/erlang or hexpm/elixir carries the tag
across every architecture.
When Docker Hub prunes images that aren't being pulled, the checker saw
them missing and rebuilt them every cycle, only for them to be pruned
again. Gate the automatic erlang/0 and elixir/0 enqueues on freshness:
build only when the base image, OTP, or Elixir version was released
within the last 30 days. Base-image recency now relies on first-seen,
so replace_base_image_tags preserves inserted_at instead of rewriting
it each reconcile. User-requested builds bypass the gate, so pruned old
versions can still be pulled back on demand.
…nd-requests

# Conflicts:
#	lib/bob/queue/maintenance.ex
#	test/bob/queue/maintenance_test.exs
The nav tagline that used .bob-brand__tag is gone from the layout, so
the rule and its responsive-hide selector were dead CSS.
- Reject /\ protocol-relative paths in safe_return_path, not just //.
- Reuse filter_select with an optional prompt instead of a near-clone
  form_select in the request form.
- Skip non-library/ repos in recent_base_image_versions rather than
  crashing the checker on an unexpected base-image repo.
- Cache the checker's GitHub fetches briefly so erlang() and elixir()
  don't re-fetch the same refs/releases within a cycle.
- Stop persisting the access token: it is never reused after login, so
  only the refresh token (for refresh and logout revocation) is kept.
- Serialize a user's concurrent submits with a per-user advisory lock so
  the hourly-limit check and insert can't both slip past the cap.
@ericmj ericmj merged commit 50272f9 into main Jun 16, 2026
4 checks passed
@ericmj ericmj deleted the latest-patch-builds-and-requests branch June 16, 2026 18:24
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