| name | release-and-rollout |
| description | How a change in this repo actually reaches CI - the two tag series, cutting a v* source tag, publishing an orb version, and bumping consumer pins. Read this before or after merging any fix that needs to run in production CI. |
Release and rollout
Merging a PR here deploys nothing. There are two independent release channels, and a
change only reaches CI once both have been advanced and the consumer's orb pin bumped.
Two tag series - don't confuse them
| Tag | Releases |
|---|
vX.Y.Z | The source tree (github_utility/, scripts) that jobs clone at runtime |
orb/X.Y.Z | Bookkeeping mirror of a published CircleCI orb version |
The two version numbers are unrelated. Orb versions live in CircleCI, not in git -
orb/* tags are only created after the fact by orb/publish-prod-repository-tag.sh
and are not what CircleCI serves.
Why merging deploys nothing
orb/src/commands/setup-circleci-utils-and-github-token.yml clones this repo at a tag:
git clone --branch << parameters.circleci-utils-tag >> --depth 1 \
https://github.com/ethereum-optimism/circleci-utils.git /tmp/circleci-utils
circleci-utils-tag has a default in that file, and that default is frozen into every
published orb version. A consumer runs whatever tag its pinned orb version was published
with, no matter what main says.
No orb command forwards circleci-utils-tag to the setup command, so consumers cannot
pick up new source code by passing a parameter to the command they actually call.
The full chain
- Merge the PR to
main.
- Cut a source tag at the merge commit:
git tag vX.Y.Z <merge-sha> && git push origin vX.Y.Z.
- Bump
circleci-utils-tag's default to vX.Y.Z in
orb/src/commands/setup-circleci-utils-and-github-token.yml and merge that.
- Publish a new orb version -
orb/publish-dev.sh, test, then orb/publish-prod.sh -
and push the orb/X.Y.Z tag. See Development & Release Process.
- Bump every consumer's orb pin. For the monorepo that's
ethereum-optimism/circleci-utils@<version> in .circleci/continue/main.yml.
Nothing is live until step 5.
Steps 2 and 3 apply only to changes in the cloned source tree. A change to orb YAML alone
needs steps 1, 4 and 5.
Who can publish
Publishing a production orb version requires GitHub org Owner; org Members can only
publish dev: versions. If you're not an owner, ask in #eng-oncall - see
Permissions & Access.
Checking what's actually published
The orb is private, so https://circleci.com/api/v2/orb/ethereum-optimism/circleci-utils
returns 404. Use the CircleCI GraphQL API instead; reads need no token.
List published versions:
curl -s https://circleci.com/graphql-unstable \
-H 'Content-Type: application/json' \
-d '{"query":"{ orb(name: \"ethereum-optimism/circleci-utils\") { isPrivate versions { version createdAt } } }"}'
Read a published version's full source - the only reliable way to see which
circleci-utils-tag a version really shipped with:
curl -s https://circleci.com/graphql-unstable \
-H 'Content-Type: application/json' \
-d '{"query":"{ orbVersion(orbVersionRef: \"ethereum-optimism/circleci-utils@1.0.30\") { source } }"}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["data"]["orbVersion"]["source"])' \
| grep -A2 circleci-utils-tag
Escape hatch for an urgent rollout
A consumer can force a source tag without waiting on an orb publish, by running the setup
command itself first with an explicit tag:
- utils/github-stale:
pre-steps:
- utils/setup-circleci-utils-and-github-token:
circleci-utils-tag: vX.Y.Z
This works because the setup command clones only if /tmp/circleci-utils doesn't exist,
so the later internal call is a no-op.
Use it as a temporary bridge only. Publishing an orb version is the right fix - an override
has to be repeated in every consumer and leaves the stale default in place everywhere else.
Verify after rollout
Check a real job on the consumer, not just the config diff. The Setup circleci-utils step
logs the tag it clones; if it's still the old one, the orb version you pinned still carries
the old default - go back to step 4.
Checklist