astronomer/Otto Airflow Upgrade

Scheduled, Otto-driven Airflow upgrades: detect the current Runtime + providers, bump to a safe target, have Otto migrate the DAG code for breaking changes, verify, and open a PR.

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Activelast commit Jun 23, 2026
License
Apache 2.0

Pinned Snippet

workflow.ymlSHA-pinned
uses: astronomer/otto-upgrade-action@51d37cb222c9d6e1432fc082537d271dbf4e3b49 # v0.1.0

tags can be moved; commit SHAs can't. why a SHA?

namedescriptionrequireddefault
astro-api-tokenAstronomer API token for the Otto code-migration step. If empty, falls back to the ASTRO_API_TOKEN env var. When no token is available the action still opens the version-bump PR, but skips the Otto migration and flags breaking changes for manual review.no""
astro-domainAstronomer domain. Override for non-prod (e.g. 'astronomer-dev.io').noastronomer.io
astro-organizationAstronomer organization ID for gateway routing. Falls back to the ASTRO_ORGANIZATION env var.no""
github-tokenToken used to push the branch and open/update the PR. Needs contents:write and pull-requests:write. To have the upgrade PR itself trigger your other CI workflows, supply a PAT or GitHub App token instead of the default GITHUB_TOKEN.no${{ github.token }}
project-pathPath to the Astro project root (the directory containing the Dockerfile and requirements.txt).no.
targetHow far to bump the Runtime: 'patch' (newest build on the current Airflow minor), 'latest-minor' (newest Runtime within the current Airflow major), or 'latest' (newest stable Runtime). Always clamped by max-upgrade-scope.nolatest-minor
max-upgrade-scopeSafety clamp on how big a jump may be auto-authored: 'patch', 'minor', or 'major'. Majors are advisory-only regardless of this value — a scheduled bot never auto-authors an Airflow major migration; it surfaces it for the guided upgrade instead.nominor
include-providersAlso bump pinned 'apache-airflow-providers-*' entries in requirements.txt. Unpinned providers are reported but never changed.notrue
verify-levelPost-upgrade verification: 'parse' (default — build the project's Docker image at the target Runtime and run Astro's DAG integrity tests inside it; catches image-build failures and verifies DAGs in the production-faithful environment; needs Docker, falls back to 'import' without it), 'import' (import the discovered DAG + plugin files in a PyPI-built env), 'syntax' (byte-compile only), or 'none'. Verification fails only on a NEW failure the upgrade introduces — failures that already occur at your current versions are reported but don't fail the run; env/setup problems report 'skipped'.noparse
bump-blocking-pinsWhen a provider bump conflicts with one of YOUR pins, raise your pin to the newest version uv can co-resolve instead of holding the provider back. Off by default — it edits user-owned dependencies. Every raise is listed in the PR's version table and gated by verification like any other change; if uv can't resolve a raise, the provider is held as usual.nofalse
deprecation-cleanupDeprecated-Airflow-usage sweep (ruff AIR3 rules, dags/+plugins/+include/ only) beyond the hop's own migrations: 'fix' (default — mechanically rewrite what ruff can, e.g. operators moved to providers; remaining debt is listed in the PR), 'advisory' (only list the debt, change nothing), or 'off'. 'fix' auto-demotes to advisory when the target Airflow is not 3.x (the rewrites produce Airflow 3 forms) or when verify-level is below 'import' (nothing would gate the rewrites). Your own ruff excludes, per-file-ignores, and noqa comments are honored.nofix
base-branchPR base branch. Empty uses the currently checked-out branch.no""
branchHead branch for the rolling upgrade PR. Re-runs force-push to it and update the same PR in place rather than opening a new one each run.nootto/airflow-upgrade
labelsComma-separated labels applied to the PR (best-effort; missing labels are skipped with a warning).noairflow-upgrade,dependencies
modelModel identifier passed to Otto via --model. Empty uses Otto's default.no""
astro-cli-versionAstro CLI version to install for the Otto step. Empty installs the latest published version (recommended). Only consulted when the Otto migration step runs.no""
dry-runCompute the plan, apply the bumps locally, and write the would-be PR body to the job summary — but do not push or open a PR. Use this to preview what the action would do.nofalse
namedescription
current-runtimeDetected current Runtime tag.
target-runtimeResolved target Runtime tag.
overall-scopeLargest tier across the resolved plan (after pin reconciliation): patch, minor, major, or none.
no-update'true' when nothing is behind and the action no-ops.
verify-statusVerification result: passed, failed, or skipped (skipped when verification didn't run).
security-fixesCount of security fixes listed in the Runtime release notes for the target's release line — a lower bound for cross-line upgrades. 'unknown' when it couldn't be determined, empty when the runtime didn't change.
pr-numberNumber of the opened/updated PR (empty in dry-run or no-op).
pr-urlURL of the opened/updated PR (empty in dry-run or no-op).
branchHead branch the upgrade was committed to.