Deprecation and removal notice: v1alpha1, v2alpha1, and Classic¶
Audience: Platform engineer / tenant operator
Three deprecations, one removal release: v2.0.0
Onboard new tenants on the v2 API at actions-gateway.com/v2beta1 (see
Getting Started),
and author them as single-label ScaleSet runner sets. Everything named below
stays fully served until v2.0.0, so nothing is forced today. Migrate
existing tenants with gag-migrate at your
convenience: the move changes the API objects, not how jobs are acquired.
This page is the project's standing deprecation notice. It records what v2.0.0
removes, what keeps working until then, and what an operator has to do before
upgrading past it. One further deprecation runs on its own, later clock —
the CiliumFQDN / CalicoFQDN egress modes,
removable no earlier than v3.0.0.
What v2.0.0 removes¶
Removed at v2.0.0 |
What it is today | What replaces it | How you move |
|---|---|---|---|
actions-gateway.github.com/v1alpha1 |
the monolithic ActionsGateway (inline proxy and runnerGroups[]) plus the standalone RunnerGroup kind |
the decomposed actions-gateway.com API at v2beta1 |
gag-migrate, a one-shot fan-out of one v1 object into several v2 objects |
actions-gateway.com/v2alpha1 |
v2's first served version, superseded as storage and hub version by the v2beta1 graduation |
v2beta1, the graduated, ScaleSet-only shape |
read and re-apply your objects at v2beta1; the conversion webhook already round-trips them, so there is no re-author step except for the two v2alpha1-only fields below |
Classic acquisition (RunnerSet.spec.acquisitionProtocol: Classic and spec.maxListeners, both v2alpha1-only) |
the many-acquirers protocol, and the only protocol v1alpha1 speaks |
ScaleSet, the single-acquirer protocol: the default since v1.1.0, and the only protocol v2beta1 serves |
create one fresh single-label ScaleSet RunnerSet per runs-on target. acquisitionProtocol is immutable, so this is a create-and-delete, not an edit |
v2beta1 itself is not affected. Beta's contract is that a version will not be
removed, and v2.0.0 adds the GA v2 version beside it rather than taking it away.
Why the three are coupled¶
v2beta1 is already ScaleSet-only, so classic acquisition exists only to serve
v1alpha1 and v2alpha1 objects. Removing those two versions removes classic's
entire reason to exist. Splitting the three removals across separate releases would
buy nothing and would cost every operator a second breaking migration, so they land
together on one major tag.
A fourth deprecation on a different clock: CiliumFQDN / CalicoFQDN¶
The EgressProxy field spec.egressPolicyMode accepts two deprecated per-Container
Network Interface (CNI) values, CiliumFQDN and CalicoFQDN, superseded by the
FQDN intent plus the operator's --fqdn-policy-backend selector
(security-operations).
They are not part of the v2.0.0 bundle above.
The earliest release that may remove them is v3.0.0.
Why they cannot ride the v2.0.0 clock:
- They are elements of a beta version, not a version themselves. The two values
exist in
v2alpha1and inv2beta1, which is the storage and hub version. Thev2alpha1copy disappears withv2alpha1atv2.0.0; thev2beta1copy does not, becausev2.0.0keeps servingv2beta1— it adds the General Availability (GA)v2version beside it. - An API element is removed by incrementing the version, never by deleting it from
a served one. Deleting a value from a version already in the field would reject
objects an operator has stored and can still
kubectl apply— the exact breakage the versioning contract exists to prevent. So the values live for as long asv2beta1is served. - Beta promises the version will not be removed without a migration path. Retiring
a served version is a breaking change, and this project lands breaking changes on a
major tag announced at least one release ahead (roadmap). The next
major after
v2.0.0isv3.0.0, so that is the earliest tag that can retirev2beta1and, with it, these two values.
Naming v2.0.0 for them would have been a promise the API contract forbids keeping:
the removal would have had to either break v2beta1 objects or quietly not happen.
Two consequences worth stating plainly:
v3.0.0is not scheduled and carries no date, exactly asv2.0.0carries none. It is gated onv2beta1's retirement, which is gated in turn on thev2GA soak (v2 GA plan). The commitment here is a floor — not beforev3.0.0— and the removal still gets its own one-release-ahead announcement.- Whether the GA
v2version defines the two values at all is a separate, open question, settled by the graduation hop rather than by this notice.v2is a new version, so it is free to omit them; if it does, an operator onv2simply cannot set them, while an operator onv2beta1still can untilv3.0.0. Either way the removal release above is unchanged.
What to do now: nothing is forced, but migrate when convenient — set
egressPolicyMode: FQDN on the EgressProxy and have the platform operator set the
matching GMC --fqdn-policy-backend. The admission webhook already warns on every
write that still names a deprecated value, and the warning names v3.0.0.
Status¶
- All three are deprecated and still fully served. No release has removed any of
them. Existing tenants keep running unchanged until they upgrade past
v2.0.0. - New tenants should onboard on
v2beta1. See tenant onboarding for the v2 object set. v2alpha1stays served as thegag-migrateon-ramp. It carries theacquisitionProtocolselector a migrating v1 tenant needs, which a new tenant does not. Note that alpha's contract allows an alpha version to be dropped without notice; namingv2.0.0for it is a stronger commitment than the maturity level requires.- Existing tenants migrate with the tool on their own schedule: see migration-v1-to-v2.md. The migration is a one-shot fan-out, not an automatic conversion, because one v1 object becomes several v2 objects.
- Migrating preserves how your jobs are acquired.
gag-migratemaps v1 runner groups to v2RunnerSets that use the same job-acquisition path: it writesacquisitionProtocol: Classiconto every emitted set, so the migration changes the API objects, not the runtime behaviour, and is safe to do ahead of any other change. AdoptingScaleSetfor a migrated group is a distinct, later step (create a fresh single-label set), never a side effect of migrating offv1alpha1.
Why v2 (what the decomposition buys)¶
- Reusable pod templates. The large
PodTemplateSpecmoves to a referencedRunnerTemplate/ClusterRunnerTemplate, so one template is shared by manyRunnerSets instead of being copied into every group. - Multiple gateways per namespace. The v1 one-gateway-per-namespace rule is dropped.
- Standalone / shareable egress proxy. The inline proxy becomes an
EgressProxykind any number ofRunnerSets can point at. - Namespace-scoped Pod Security profile.
securityProfilemoves off the per-gateway spec onto the namespace, matching how Pod Security Admission actually works. - Single-acquirer job acquisition.
ScaleSetholds one listener per runner set, so GitHub never assigns beyond advertised capacity. Classic's many-acquirers model can mark a jobin_progressand then fail to provision a worker for it; measured on this project's own dogfood tenant, that orphaned 81% of acquired jobs (troubleshooting).
Full rationale: Appendix H.
The dual-read window (what keeps working during coexistence)¶
The v2 cutover also aligns two grandfathered, boolean-looking label/annotation values
and moves the project's domain-prefixed keys off actions-gateway.github.com/ onto
actions-gateway.com/ (Q147 / the API-group rename). During coexistence both
consumers of these values, the ValidatingAdmissionPolicy objects and the GMC
validating webhook, dual-read both spellings:
| Key | Legacy (v1) | Aligned (v2) |
|---|---|---|
| tenant marker | actions-gateway.github.com/tenant: "true" |
actions-gateway.com/tenant: managed |
| PSA profile | ActionsGateway.spec.securityProfile |
actions-gateway.com/security-profile (namespace label) |
| privileged eligibility | actions-gateway.github.com/privileged-profile: allowed |
actions-gateway.com/privileged-profile: allowed |
| downgrade opt-in | actions-gateway.github.com/allow-profile-downgrade: "true" |
actions-gateway.com/allow-profile-downgrade: allowed |
| finalizers | actions-gateway.github.com/gmc-cleanup, …/agentpool-cleanup |
actions-gateway.com/gmc-cleanup, …/agentpool-cleanup |
The migration tool relabels these in one pass (additively: it adds the v2 keys and
keeps the v1 keys). The dual-read only widens accepted spelling, it never relaxes
an invariant. The window closes at v2.0.0, when v1alpha1 is removed and the
legacy "true" arms and the actions-gateway.github.com/* keys are dropped from the
policies and the webhook.
The removal release, and what it is gated on¶
v2.0.0 is the named removal release, announced with v1.3.0. The project's
policy is that a removal lands on a named release announced at least one release
ahead (roadmap); v1.3.0 carries that announcement for all three
items above.
v2.0.0 is a major tag because removing a served API version is a breaking
change, and it is gated on the v2 (GA) API being available and validated, not on
a date and not on an adopter census. Gating on v2 maturity is
what lets the commitment be concrete: you are never asked to move onto an alpha to
escape a removal, and there is no census to wait on. v2beta1 is production-relyable
today and converts to v2 in place.
There is deliberately no date. v1.3.0 fixes which release removes these and
what it removes; the GA soak that gates v2.0.0 finishes when the evidence says
the v2 shape is right.
Before you upgrade past v2.0.0¶
- Migrate off
v1alpha1. Rungag-migrate, which also relabels the namespace markers and annotations onto theactions-gateway.com/spellings. Do this before upgrading: after removal the legacy spellings and the v1 finalizer names are no longer honored, and any remainingv1alpha1objects have no served version. - Move
v2alpha1objects tov2beta1. Re-apply them atv2beta1(or let the conversion webhook serve them there and re-record your GitOps manifests at that version) so nothing in Git still names a removed version. - Replace Classic runner sets with
ScaleSetsets. One single-labelRunnerSetperruns-ontarget, created fresh, sinceacquisitionProtocolis immutable. Split any multi-label group into one set per label, and dropmaxListeners, whichScaleSetignores. See tenant onboarding.
Until that release, no action is forced: run gag-migrate
when convenient, validate the v2 path, and decommission v1 at your own pace.