Image manifest
The image manifest is usually stored at .github/image_manifest.yaml in the
deployment repos. It is the config that
bump-images reads to decide which manifests an incoming
image touches, how the change lands, and who was allowed to send it.
It can be dry-run against a canned payload with
odp-releaser test bump-images,
and statically checked with
odp-releaser validate image-manifest.
Example image manifest
Example image_manifest.yaml with documentation can be generated via the CLI.
$ odp-releaser generate-config image-manifest
# Configuration for image manifests, mapping image names to their update configurations.
# Default settings applied to every image config; a config's own value replaces the default
defaults:
# Full repo names (owner/name) allowed to trigger bumps; None disables the check
allowed_source_repos:
- gulfofmaine/Neracoos-1-Buoy-App
- ioos/buoy_retriever
# Users and teams allowed to trigger bumps; None disables the check
allowed_actors:
# GitHub usernames, compared case-insensitively against the payload's source actor
users:
- abkfenris
# GitHub teams as org/team-slug entries. Membership is checked with the source org's reporter app credentials (REPORTER_APPS / REPORTER_APP_ID / REPORTER_APP_PRIVATE_KEY), so that app must also be granted the organization Members: read permission
teams:
- gulfofmaine/deployers
# Default GitHub environment name used when reporting deployments back to source repos (`report-deployment`). Overridable per image config; unset falls back to this deploy repo's owner/name slug
environment: staging
# Default URL reported as the deployment's 'View deployment' link. May reference `{new_tag}`, `{git_sha}`, and `{digest}`. Overridable per image config; unset falls back to the bump commit or pull request URL
environment_url: https://staging.neracoos.org
# Default comment posted back on source pull requests when images are bumped. Overridable per image config, field by field; unset falls back to the built-in templates
comment:
# Comment body posted once the bump has landed -- immediately for a commit-mode bump, or when the bump pull request merges. Unset inherits the defaults-level value, then the built-in template
deployed: '`{image_name}` `{new_tag}` deployed to `{environment}`'
# GitHub usernames requested as reviewers on bump pull requests
reviewers:
- abkfenris
# GitHub team slugs (no org prefix) requested as reviewers on bump pull requests. The bump-images workflow detects this key and mints its app token with organization Members: read (the ci app must be granted the permission)
team_reviewers:
- deployers
# Mapping of image names to their configurations
images:
gmri/neracoos-mariners-dashboard:
# Configuration for an image, specifying which manifests to update and how.
-
# List of GitHub events for these manifests. Only these events will trigger updates. If `None`, all events trigger updates.
events:
- publish
# Full repo names (owner/name) allowed to trigger this config. Replaces the defaults-level list; unset inherits it. A config whose resolved list rejects the payload's repo is skipped
allowed_source_repos:
- gulfofmaine/Neracoos-1-Buoy-App
# Users and teams allowed to trigger this config. Replaces the defaults-level setting; unset inherits it. A config whose resolved actors reject the payload's actor is skipped. Use YAML merge keys (<<: *anchor) to share allowlists between configs
allowed_actors:
users:
- abkfenris
# GitHub environment name reported back to the source repo for this config's bumps (`report-deployment`). Overrides the defaults-level environment; unset falls back to the deploy repo's owner/name slug
environment: production
# URL reported as the deployment's 'View deployment' link, e.g. where this config's app runs. May reference `{new_tag}`, `{git_sha}`, and `{digest}`. Overrides the defaults-level environment_url; unset falls back to the bump commit or pull request URL
environment_url: https://mariners.neracoos.org
# Whether to commit the change directly or open a pull request for review
update_mode: pull_request
# GitHub usernames requested as reviewers when this config's bump opens a pull request. Replaces the defaults-level list; unset inherits it, [] requests none
reviewers:
- abkfenris
# GitHub team slugs (no org prefix) requested as reviewers on the bump pull request. Replaces the defaults-level list. The bump-images workflow detects this key and mints its app token with organization Members: read
team_reviewers:
- mariners
# The image name the manifests under this config actually deploy from, when it differs from the payload's image_name -- e.g. an ECR pull-through cache path such as '123456789.dkr.ecr.us-east-1.amazonaws.com/docker-hub/gmri/sea-eagle-brown-3crs' mirroring upstream 'gmri/sea-eagle-brown-3crs'. Used as the Helm dagster shorthand's image.repository selector and in `set` templating via `{deployed_image}`; kustomize's own `newName` already carries the mirror, so this does not change which `images:` entry kustomize matches. Per-config only
deployed_as:
123456789.dkr.ecr.us-east-1.amazonaws.com/docker-hub/gmri/neracoos-mariners-dashboard
# List of Kustomize manifests to set for the image
kustomize_manifests:
- ../apps/mariners/kustomization.yaml
# List of Helm values files to update for the image
helm_charts:
# Helm manifest configuration with Dagster user deployments chart layout shorthand.
-
# Relative path to the Helm values file
path: ../apps/sea-eagle/values.yaml
# When true, update the image.tag of every entry in the top-level 'deployments' list whose image.repository matches the released image (Dagster user-deployments chart layout)
dagster_user_code: true
# List of generic YAML or JSON manifests updated via set paths
file_manifests:
# A generic YAML or JSON manifest updated purely via ``set`` paths.
# Unlike the kustomize and helm manifests there is no implicit image field
# to update, so a bare-string form carries no useful information; the mapping
# form with an explicit ``set`` is required.
-
# Relative path to the file manifest
path: ../apps/config/deployment.json
# Mapping of yamlpath expressions to templated values. Values may reference `{new_tag}`, `{git_sha}`, `{digest}`, `{payload}`, and `{deployed_image}` (the config's `deployed_as`, or the payload's image name when it declares none)
set:
/spec/template/spec/containers[0]/image: gmri/example@{digest}
- events:
- push
# Comment posted back on the source pull request for this config's bumps. Each field is inherited from the defaults-level setting independently, so overriding one template keeps the other
comment:
deployed: '`{image_name}` `{new_tag}` is live on dev'
update_mode: commit
deployed_as: ghcr.io/gulfofmaine/neracoos-mariners-dashboard-dev
# Whether odp-releaser copies the payload's image to deployed_as before the bump lands. Unset or false means declare-only: the correct setting for ECR pull-through and any other registry-native replication, where there is nothing to copy because the cache populates itself on the next pull. Overrides the defaults-level value; unset inherits it, then falls back to false
sync: true
kustomize_manifests:
# Kustomize manifest configuration. Updates the image overrides and set fields.
-
# Relative path to the Kustomize manifest
path: apps/mariners-dev/kustomization.yaml
# Whether the kustomize images entry pins the tag (newTag) or the immutable digest (digest)
pin: digest
helm_charts:
- path: ../apps/sea-eagle/values.yaml
dagster_user_code: true
file_manifests:
- path: ../apps/config/deployment.json
set:
/spec/template/spec/containers[0]/image: gmri/example@{digest}
Manifests
For each of the manifest types, the set key takes a dictionary of yamlpath selectors and templated values to update.
Templated set values:
The values are templated with parts of the client payload.
Example values
new_tag-7c8d9e0git_sha-7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6ddigest-sha256:2a4b6c8d0e1f3a5b7c9d0e2f4a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2bpayload-{"image_name":"ghcr.io/ioos/buoy_retriever_s3_timeseries","digest":"sha256:2a4b6c8d0e1f3a5b7c9d0e2f4a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b","tag":"7c8d9e0","git_sha":"7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d","image_ref":"ghcr.io/ioos/buoy_retriever_s3_timeseries@sha256:2a4b6c8d0e1f3a5b7c9d0e2f4a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b","source":{"event":"push","ref":"main","url":"https://github.com/ioos/buoy_retriever/pull/142","run_url":"https://github.com/ioos/buoy_retriever/actions/runs/1200000002","actor":"abkfenris","release":null,"pr":{"number":142,"title":"Add hourly S3 timeseries ingest","url":"https://github.com/ioos/buoy_retriever/pull/142"}},"repo":"ioos/buoy_retriever"}
One additional placeholder isn't in that list because it isn't part of the
payload: {deployed_image}, the name this config's manifests actually deploy
from (deployed_as when set, otherwise the payload's own image_name). See
Syncing images.
KustomizeManifest
pydantic-model
Bases: BaseModel
Kustomize manifest configuration. Updates the image overrides and set fields.
Fields:
Validators:
-
coerce_path_string
pin
pydantic-field
pin: Literal['tag', 'digest']
Whether the kustomize images entry pins the tag (newTag) or the immutable digest (digest)
__get_pydantic_json_schema__
classmethod
__get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler) -> JsonSchemaValue
Also accept the bare-path shorthand coerce_path_string allows.
model_json_schema() only sees the mapping form, so the generated
schema in schemas/ (used for editor completion and
check-jsonschema) would flag the documented
- ./kustomization.yaml shorthand as an error. Declaring the union
here keeps the published schema honest about what the model really
validates.
Source code in src/odp_releaser/schemas/manifest_config.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
HelmManifest
pydantic-model
Bases: BaseModel
Helm manifest configuration with Dagster user deployments chart layout shorthand.
Fields:
FileManifest
pydantic-model
Bases: BaseModel
A generic YAML or JSON manifest updated purely via set paths.
Unlike the kustomize and helm manifests there is no implicit image field
to update, so a bare-string form carries no useful information; the mapping
form with an explicit set is required.
Fields:
Deploying from a mirrored registry
A config whose manifests deploy from a mirror rather than the payload's own
image name declares that with deployed_as, and can have odp-releaser push the
image there with sync: true. Both settings, how each manifest engine consumes
them, and the credentials a sync needs have their own page:
Syncing images.
Pull request comments
When the reporter app has been granted Pull requests: Read and write (see
GitHub App), a bump also comments on the
source pull request saying which image landed and where. There are two
templates, because a bump has two states worth distinguishing:
staged— apull_request-mode bump has opened a pull request in the deploy repo but nothing is live yet.deployed— the bump has landed: immediately forupdate_mode: commit, or when the bump pull request merges, at which pointreport-merged.ymlrewrites the staged comment in place.
Each comment is keyed to one (deploy repo, image, environment) triple, so a
rerun edits the same comment rather than adding another, and sibling bumps never
overwrite each other on the same pull request.
Both templates are inherited field by field — a config that overrides only
staged keeps the defaults-level deployed, and an unset field falls back to
the built-in template. That differs from every other setting, where a config's
value replaces the default wholesale, because the two templates describe
different states and are meant to be set independently.
Only push events carry a source pull request (that's the only event
odp-releaser notify resolves one for), so nothing is posted for release or
workflow_dispatch dispatches; odp-releaser validate image-manifest
warns when a config asks for a comment it could never post. Set enabled: false
to turn commenting off, or a template to "" to post nothing in that one state.
The built-in templates
These are what you get when neither level sets a template — and a useful starting point for an override:
comment:
staged: |
### `{image_name}` staged for `{environment}`
Tag `{new_tag}` is staged in [`{deploy_repo}`]({bump_url}) and is waiting on review before it deploys.
<sub>Bumped by [odp-releaser]({run_url}) from `{git_sha}`.</sub>
deployed: |
### `{image_name}` deployed to `{environment}`
Tag `{new_tag}` landed in [`{deploy_repo}`]({bump_url}).
<sub>Bumped by [odp-releaser]({run_url}) from `{git_sha}`.</sub>
Rendered against a real bump, the deployed one comes out as:
from odp_releaser.bump_image_tester import EventType, load_client_payload
from odp_releaser.comment_body import CommentState, build_context, render_comment
from odp_releaser.schemas.manifest_config import DEFAULT_DEPLOYED_TEMPLATE
payload = load_client_payload(EventType.push)
context = build_context(
payload,
deploy_repo="gulfofmaine/deploy-repo",
environment="production",
environment_url=None,
update_mode="commit",
bump_url="https://github.com/gulfofmaine/deploy-repo/commit/9f8e7d6",
run_url="https://github.com/gulfofmaine/deploy-repo/actions/runs/123",
state=CommentState.deployed,
)
print(render_comment(DEFAULT_DEPLOYED_TEMPLATE, context))
### `ghcr.io/ioos/buoy_retriever_s3_timeseries` deployed to `production`
Tag `7c8d9e0` landed in [`gulfofmaine/deploy-repo`](https://github.com/gulfofmaine/deploy-repo/commit/9f8e7d6).
<sub>Bumped by [odp-releaser](https://github.com/gulfofmaine/deploy-repo/actions/runs/123) from `7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d`.</sub>
<!-- odp-releaser:comment key=gulfofmaine/deploy-repo|ghcr.io/ioos/buoy_retriever_s3_timeseries|production -->
That trailing HTML comment is the marker described above — it is invisible on the rendered pull request, and it is how a rerun finds the comment to update.
Comment placeholders
Comment templates are rendered with str.format, like set values — but
against their own, larger vocabulary, since a comment can reference deploy-side
facts that have no business being templated into a manifest:
{image_name}{image_ref}{new_tag}{digest}{git_sha}{source_repo}{source_url}{actor}{deploy_repo}{environment}{environment_url}{update_mode}{bump_url}{run_url}{state}
Because rendering goes through str.format, a literal brace has to be
doubled: write {{ for { and }} for }. This matters for markdown that
contains a Helm or Go template, or a ${{ ... }} expression:
comment:
deployed: |
`{image_name}` is now `{new_tag}` in [{deploy_repo}]({bump_url}).
Pinned with `{{{{ .Values.image.tag }}}}`.
An unknown placeholder or a stray single brace is reported by
odp-releaser validate image-manifest before a release, rather
than failing mid-bump.
CommentConfig
pydantic-model
Bases: BaseModel
Comment posted back on the source pull request when this image is bumped.
Every field is optional and inherited independently: an unset field takes
the defaults-level value, then the built-in template. See
:func:resolve_comment_config.
Fields:
deployed
pydantic-field
deployed: str | None
Comment body posted once the bump has landed -- immediately for a commit-mode bump, or when the bump pull request merges. Unset inherits the defaults-level value, then the built-in template
enabled
pydantic-field
enabled: bool | None
Whether to comment on the source pull request for this config's bumps. Unset inherits the defaults-level value, which itself defaults to true
staged
pydantic-field
staged: str | None
Comment body posted while a pull_request-mode bump is open and awaiting review. May reference the comment placeholders (see the docs); escape literal braces as {{/}}. Unset inherits the defaults-level value, then the built-in template
Validating
The config is read by pydantic models with the default extra="ignore", so a
typo'd key (kustomize_manifest: instead of kustomize_manifests:) is silently
dropped rather than rejected. Nothing about that runtime path tells the author
their key never took effect. Worse, the checks that would catch a typo'd or
malformed value — a yamlpath selector that never resolves, a {sha}
placeholder that should have been {git_sha}, a manifest path that doesn't
exist — otherwise only run partway through a real bump, in CI, against a real
payload, often after earlier manifests in the same run have already been
written.
odp-releaser validate image-manifest runs all of those checks statically and
offline: no GitHub API calls, no writes, just the config file(s) on disk. It's
meant to run in CI on a config repo, as a
pre-commit hook, or by hand before a
config change is merged.
odp-releaser validate image-manifest
odp-releaser validate image-manifest .github/image_manifest.yaml
A clean file prints a one-line ✓ <path> to stdout. Problems are printed to
stderr as path:line: severity: message, one per line, colored by severity. The
command exits 1 if any file has errors, or — with --strict — if any file has
warnings, so a repo that wants warnings to block CI can opt in:
odp-releaser validate image-manifest --strict
image-manifest also accepts --no-check-files, for a repo where the manifests
an image_manifest.yaml points at (Kustomize/Helm/plain YAML files) don't live
in the same checkout the validator is run against:
odp-releaser validate image-manifest --no-check-files
Relaxing validation
There is no way to switch off one individual check by name (#47 tracks whether there should be). What exists instead:
- Severity. Warnings never fail a run unless you pass
--strict, andbump-imagesnever fails on a warning at all. A check whose correctness depends on something the validator can't see — cluster state, another process — is a warning for exactly this reason, so the usual answer to "this finding doesn't apply to us" is to not run--strict. --no-check-files. Skips every check that has to read a referenced manifest: selector resolution, the kustomize pin andnewNamechecks, the Helm dagster check, and the engine backstop. Coarse, but it is the one flag that turns off a whole family.- pre-commit. The hooks are ordinary pre-commit hooks, so a consumer repo
can skip one for a single commit (
SKIP=validate-image-manifest git commit), narrow what it runs against withfiles:/exclude:, or pass flags through withargs: [--no-check-files].
If a check is wrong for a legitimate config rather than merely unwanted, that's worth reporting as a bug — a rule that a correct config cannot satisfy is a defect in the rule, not something to suppress.
What is checked
Every check exists because a config that is shaped correctly can still mean something the runtime code mishandles. The tables below list each check's consequence at bump time — that's the reason it exists.
Errors (always fail the run):
| Check | Consequence if not caught |
|---|---|
| Unknown key anywhere in the config | The key is silently dropped by pydantic; the setting the author intended never takes effect |
| Schema validation failure (wrong type, missing required field, ...) | bump-images never gets a validated config to run against at all |
images key isn't a valid image name (empty, whitespace, uppercase, contains @/:) |
Can never equal a real payload's image_name, so this config can never match a bump |
allowed_source_repos entry isn't an owner/name pair |
Can never equal the payload's repo, so this entry can never match |
allowed_actors.teams entry isn't an org/team-slug pair |
The team-membership check hard-exits the whole run |
team_reviewers entry has an org/ prefix |
GitHub's "request review from teams" API expects a bare slug; the request fails |
A set selector is not a valid yamlpath |
bump-images fails trying to apply the same selector |
A set selector does not resolve against its target manifest |
Processor.get_nodes(..., mustexist=True) raises at bump time |
A templated value uses a positional ({0}, {}), attribute/index ({payload.foo}), or unknown placeholder |
str.format(**kwargs) raises KeyError/ValueError at bump time |
| A templated value fails to actually format against a real payload | Same failure, confirmed against real value_format_kwargs() |
A comment template uses an unknown placeholder, or a single stray {/} |
odp-releaser comment can't render it; literal braces must be doubled ({{/}}). Comment templates have their own vocabulary, so a set-only placeholder like {payload} is wrong here |
kustomize_manifests[].pin: tag but /images[name=...]/newTag doesn't exist |
bump-images sets it with mustexist=True, which raises |
dagster_user_code: true but no matching /deployments[image.repository=...] entry |
bump-images sets its tag with mustexist=True, which raises |
Referenced manifest file can't be read or parsed (unless --no-check-files) |
bump-images fails the same way when it tries to load the file mid-run |
deployed_as isn't a valid image name (empty, whitespace, uppercase, contains @/:) |
Used as the Helm dagster shorthand's image.repository selector and in set templating via {deployed_image}, so it must be a plain image name like a real payload's image_name |
sync: true (directly, or inherited from defaults.sync) with no deployed_as set |
There is nothing for odp-releaser to copy the payload's image to |
| The real manifest engine raises on this manifest, even though every check above passed | bump-images fails the same way mid-run. This is the backstop: rather than predicting the engines, the validator runs them against the manifest's actual text, so a failure mode the checks above don't model is still caught |
Warnings (reported; fail the run only with --strict):
| Check | Consequence if not caught |
|---|---|
allowed_source_repos is explicitly [] |
Denies every source repository, probably not what was intended |
allowed_actors is present but both users and teams are empty |
Denies every actor |
A config has none of kustomize_manifests, helm_charts, file_manifests |
The config is a silent no-op |
reviewers/team_reviewers set but update_mode resolves to commit |
Only pull_request mode ever requests reviewers; these are never used |
| A templated value has no placeholder at all | bump-images can never change this value |
kustomize_manifests[].pin: digest but no /images[name=...] entry exists yet |
Set with mustexist=False, which won't create the missing entry |
Both newTag and digest set on the same kustomize image entry |
Kustomize prefers digest; bumping the tag has no visible effect |
| The same resolved manifest path is targeted more than once for one event | bump-images applies all of them, redundantly |
A comment is configured for an event that never carries a source pull request (anything but push) |
There is nothing to comment on, so the comment can never be posted |
comment.staged is set but update_mode resolves to commit |
A direct commit is reported as deployed immediately, so only comment.deployed is ever used |
Multiple configs matching the same event disagree on update_mode or a resolved setting (environment, environment_url, reviewers, team_reviewers, comment) |
bump-images warns and silently uses the first config's value |
deployed_as is set to the same value as this image's own images: key |
Redundant: ImageConfig.deployed_name already falls back to the images: key when deployed_as is unset, so this declares nothing new |
A kustomize manifest's /images[name=...]/newName is set but no deployed_as declares it |
sync and the Helm dagster shorthand can't see this mirror |
A kustomize manifest's /images[name=...] entry has no newName, but deployed_as is set |
Kustomize renders the upstream image rather than the mirror the config declares — which is correct if the mirror is a node-level registry mirror or pull-through cache, and wrong otherwise. Only the cluster knows which, so this reports rather than blocks |
A kustomize manifest's /images[name=...]/newName disagrees with deployed_as |
The manifest and the config name different registries. Usually a mistake, so the deploy pulls the wrong image — but legitimate if something else populates newName's registry, so this reports rather than blocks |
A file_manifests set value hard-codes the upstream image name while deployed_as is set on the same config |
Almost certainly meant to reference {deployed_image} instead — otherwise the wrong registry gets written |
Two configs writing the same resolved manifest path resolve different deployed_as values |
The manifest can only agree with one mirror; at least one config is wrong about what it actually deploys |
bump-images pre-flight
Before bump-images writes any manifest, it runs the same semantic checks
against exactly the configs it has already selected for this event (after
filtering by image name, event, and authorization) — see _preflight in
src/odp_releaser/bump_images.py. If that turns up any error, bump-images
prints them all and exits before writing anything; a problem in, say, the third
of five manifests can no longer surface as a mid-run traceback after the first
two were already written and left half-applied.
Warnings from the pre-flight are logged, not fatal — they describe configs that
work but probably don't do what their author meant, which isn't a reason to
block a release. odp-releaser validate image-manifest --strict is where
warnings are meant to block, in CI on the config repo itself.
API Reference
ManifestConfig
pydantic-model
Bases: BaseModel
Configuration for image manifests, mapping image names to their update configurations.
Fields:
defaults
pydantic-field
defaults: ConfigDefaults
Default settings applied to every image config; a config's own value replaces the default
images
pydantic-field
Mapping of image names to manifests to update
generate_yaml
classmethod
generate_yaml() -> str
Render the bundled :data:EXAMPLE_MANIFEST as commented YAML.
Source code in src/odp_releaser/schemas/manifest_config.py
585 586 587 588 | |
ImageConfig
pydantic-model
Bases: BaseModel
Configuration for an image, specifying which manifests to update and how.
Fields:
-
events(list[Literal['push', 'publish', 'workflow_dispatch', 'release']] | None) -
allowed_source_repos(list[str] | None) -
allowed_actors(AllowedActors | None) -
environment(str | None) -
environment_url(str | None) -
comment(CommentConfig | None) -
update_mode(Literal['commit', 'pull_request']) -
reviewers(list[str] | None) -
team_reviewers(list[str] | None) -
deployed_as(str | None) -
sync(bool | None) -
kustomize_manifests(list[KustomizeManifest]) -
helm_charts(list[HelmManifest]) -
file_manifests(list[FileManifest])
allowed_actors
pydantic-field
allowed_actors: AllowedActors | None
Users and teams allowed to trigger this config. Replaces the defaults-level setting; unset inherits it. A config whose resolved actors reject the payload's actor is skipped. Use YAML merge keys (<<: *anchor) to share allowlists between configs
allowed_source_repos
pydantic-field
Full repo names (owner/name) allowed to trigger this config. Replaces the defaults-level list; unset inherits it. A config whose resolved list rejects the payload's repo is skipped
comment
pydantic-field
comment: CommentConfig | None
Comment posted back on the source pull request for this config's bumps. Each field is inherited from the defaults-level setting independently, so overriding one template keeps the other
deployed_as
pydantic-field
deployed_as: str | None
The image name the manifests under this config actually deploy from, when it differs from the payload's image_name -- e.g. an ECR pull-through cache path such as '123456789.dkr.ecr.us-east-1.amazonaws.com/docker-hub/gmri/sea-eagle-brown-3crs' mirroring upstream 'gmri/sea-eagle-brown-3crs'. Used as the Helm dagster shorthand's image.repository selector and in set templating via {deployed_image}; kustomize's own newName already carries the mirror, so this does not change which images: entry kustomize matches. Per-config only
environment
pydantic-field
environment: str | None
GitHub environment name reported back to the source repo for this config's bumps (report-deployment). Overrides the defaults-level environment; unset falls back to the deploy repo's owner/name slug
environment_url
pydantic-field
environment_url: str | None
URL reported as the deployment's 'View deployment' link, e.g. where this config's app runs. May reference {new_tag}, {git_sha}, and {digest}. Overrides the defaults-level environment_url; unset falls back to the bump commit or pull request URL
events
pydantic-field
List of GitHub events for these manifests. Only these events will trigger updates. If None, all events trigger updates.
file_manifests
pydantic-field
file_manifests: list[FileManifest]
List of generic YAML or JSON manifests updated via set paths
helm_charts
pydantic-field
helm_charts: list[HelmManifest]
List of Helm values files to update for the image
kustomize_manifests
pydantic-field
kustomize_manifests: list[KustomizeManifest]
List of Kustomize manifests to set for the image
reviewers
pydantic-field
GitHub usernames requested as reviewers when this config's bump opens a pull request. Replaces the defaults-level list; unset inherits it, [] requests none
sync
pydantic-field
sync: bool | None
Whether odp-releaser copies the payload's image to deployed_as before the bump lands. Unset or false means declare-only: the correct setting for ECR pull-through and any other registry-native replication, where there is nothing to copy because the cache populates itself on the next pull. Overrides the defaults-level value; unset inherits it, then falls back to false
team_reviewers
pydantic-field
GitHub team slugs (no org prefix) requested as reviewers on the bump pull request. Replaces the defaults-level list. The bump-images workflow detects this key and mints its app token with organization Members: read
update_mode
pydantic-field
update_mode: Literal['commit', 'pull_request']
Whether to commit the change directly or open a pull request for review
deployed_name
deployed_as when set, otherwise upstream.
Resolved per config, not across configs: unlike other per-config
settings, this is deliberately never routed through
bump_images._resolve_config_setting, whose first-wins-and-warn
behaviour would silently pick one of two configs' registries.
Source code in src/odp_releaser/schemas/manifest_config.py
386 387 388 389 390 391 392 393 394 | |
matches_event
Whether this config applies to event; events: None matches every event.
Source code in src/odp_releaser/schemas/manifest_config.py
376 377 378 379 380 381 382 383 384 | |