This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch v3-0-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-0-test by this push:
new fe2aa6c8fc3 [v3-0-test] Backport gh docs publish breeze workflows
(#51286)
fe2aa6c8fc3 is described below
commit fe2aa6c8fc3ab853fdc6e092d8de4e9ed775ef21
Author: GPK <[email protected]>
AuthorDate: Mon Jun 2 10:04:40 2025 +0100
[v3-0-test] Backport gh docs publish breeze workflows (#51286)
* Add breeze commands for gh workflow docs publish (#51036)
* Add breeze commands for gh workflow docs publish
* Add breeze commands for gh workflow docs publish
* Add sync s3 to github workflow trigger
* Update dev/breeze/src/airflow_breeze/utils/gh_workflow_utils.py
Co-authored-by: Bugra Ozturk <[email protected]>
---------
Co-authored-by: Bugra Ozturk <[email protected]>
* Update GH cli bool inputs to convert to string format in breeze and input
branch to refresh site and sync s3 to github (#51093)
* Update GH cli bool inputs to convert to string format in breeze
* Update branch name to airflow-site-archive trigger
* DOCS: Remove site-refresh/sync-s3-to-github and Update release
documentation instructions (#51259)
* Remove refres sit and sync s3 to github docs args
* Update release readme files
* Update release readme files
---------
Co-authored-by: Bugra Ozturk <[email protected]>
---
dev/README_RELEASE_AIRFLOW.md | 158 +++++++++---
dev/README_RELEASE_PROVIDERS.md | 280 ++++++++++++---------
dev/breeze/doc/09_release_management_tasks.rst | 155 +++++++++---
dev/breeze/doc/images/output-commands.svg | 20 +-
.../output_setup_check-all-params-in-groups.svg | 2 +-
.../output_setup_check-all-params-in-groups.txt | 2 +-
.../output_setup_regenerate-command-images.svg | 2 +-
.../output_setup_regenerate-command-images.txt | 2 +-
dev/breeze/doc/images/output_workflow-run.svg | 103 ++++++++
dev/breeze/doc/images/output_workflow-run.txt | 1 +
.../images/output_workflow-run_publish-docs.svg | 166 ++++++++++++
.../images/output_workflow-run_publish-docs.txt | 1 +
dev/breeze/src/airflow_breeze/breeze.py | 2 +
.../airflow_breeze/commands/workflow_commands.py | 155 ++++++++++++
.../commands/workflow_commands_config.py | 36 +++
.../src/airflow_breeze/configure_rich_click.py | 5 +-
.../src/airflow_breeze/utils/gh_workflow_utils.py | 184 ++++++++++++++
17 files changed, 1067 insertions(+), 207 deletions(-)
diff --git a/dev/README_RELEASE_AIRFLOW.md b/dev/README_RELEASE_AIRFLOW.md
index cd695e78d6a..32cf8999290 100644
--- a/dev/README_RELEASE_AIRFLOW.md
+++ b/dev/README_RELEASE_AIRFLOW.md
@@ -23,10 +23,12 @@
- [Selecting what to put into the
release](#selecting-what-to-put-into-the-release)
- [Selecting what to cherry-pick](#selecting-what-to-cherry-pick)
- [Making the cherry picking](#making-the-cherry-picking)
+ - [Collapse Cadwyn Migrations](#collapse-cadwyn-migrations)
- [Reviewing cherry-picked PRs and assigning
labels](#reviewing-cherry-picked-prs-and-assigning-labels)
- [Prepare the Apache Airflow Package
RC](#prepare-the-apache-airflow-package-rc)
- [Update the milestone](#update-the-milestone)
- [Build RC artifacts](#build-rc-artifacts)
+ - [Publish release candidate documentation
(staging)](#publish-release-candidate-documentation-staging)
- [Prepare production Docker Image RC](#prepare-production-docker-image-rc)
- [Prepare Vote email on the Apache Airflow release
candidate](#prepare-vote-email-on-the-apache-airflow-release-candidate)
- [Verify the release candidate by PMC
members](#verify-the-release-candidate-by-pmc-members)
@@ -42,8 +44,7 @@
- [Publish release to SVN](#publish-release-to-svn)
- [Manually prepare production Docker
Image](#manually-prepare-production-docker-image)
- [Verify production images](#verify-production-images)
- - [Publish documentation](#publish-documentation)
- - [Wait and make sure documentation is published on the website before
proceeding](#wait-and-make-sure-documentation-is-published-on-the-website-before-proceeding)
+ - [Publish final documentation](#publish-final-documentation)
- [Notify developers of release](#notify-developers-of-release)
- [Send announcements about security issues fixed in the
release](#send-announcements-about-security-issues-fixed-in-the-release)
- [Add release data to Apache Committee Report
Helper](#add-release-data-to-apache-committee-report-helper)
@@ -140,6 +141,15 @@ to keep a reference to the original commit we cherry
picked from. ("cherry picke
git cherry-pick <hash-commit> -x
```
+## Collapse Cadwyn Migrations
+
+Before cutting an RC, bump the HEAD date of Cadwyn versioned API (execution
api for now: `airflow-core/src/airflow/api_fastapi/execution_api`)
+to reflect the tentative release date of Airflow. All the Cadwyn migrations in
between the tentative release date and last release date
+should be collapsed.
+
+Refer https://github.com/apache/airflow/pull/49116 as a good example.
+
+
## Reviewing cherry-picked PRs and assigning labels
We have the tool that allows to review cherry-picked PRs and assign the labels
@@ -331,6 +341,66 @@ pipx install -e ./dev/breeze
--current-release ${VERSION}
```
+## Publish release candidate documentation (staging)
+
+Documentation is an essential part of the product and should be made available
to users.
+In our cases, documentation for the pre-release versions is published in
`staging` S3 bucket.
+The documentation source code and build tools are available in the
`apache/airflow` repository, so
+you need to run several workflows to publish the documentation. More details
about it can be found in
+[Docs README](../docs/README.md) showing the architecture and workflows
including manual workflows for
+emergency cases.
+
+We have two options publishing the documentation 1. Using breeze commands 2.
Manually using GitHub Actions.:
+
+### Using breeze commands
+
+You can use the `breeze` command to publish the documentation.
+The command does the following:
+
+1. Triggers [Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
+2. Triggers workflow in apache/airflow-site to refresh
+3. Triggers S3 to GitHub Sync
+
+```shell script
+ breeze workflow-run publish-docs --ref <tag> --site-env <staging/live/auto>
+```
+
+The `--ref` parameter should be the tag of the release candidate you are
publishing.
+
+The `--site-env` parameter should be set to `staging` for pre-release versions
or `live` for final releases. the default option is `auto`
+if the tag is rc it publishes to `staging` bucket, otherwise it publishes to
`live` bucket.
+
+Other available parameters can be found with:
+
+```shell script
+breeze workflow-run publish-docs --help
+```
+
+### Manually using GitHub Actions
+
+There are two steps to publish the documentation:
+
+1. Publish the documentation to the `staging` S3 bucket.
+
+The release manager publishes the documentation using GitHub Actions workflow
+[Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
By default `auto` selection should publish to the `staging` bucket - based on
+the tag you use - pre-release tags go to staging. But you can also override it
and specify the destination
+manually to be `live` or `staging`.
+
+You should specify 'apache-airflow docker-stack' passed as packages to be
+built.
+
+After that step, the provider documentation should be available under
https://airflow.stage.apache.org//
+URL (RC PyPI packages are build with the staging urls) but stable links and
drop-down boxes are not updated yet.
+
+2. Invalidate Fastly cache, update version drop-down and stable links with the
new versions of the documentation.
+
+In order to do it, you need to run the [Build
docs](https://github.com/apache/airflow-site/actions/workflows/build.yml)
+workflow in `airflow-site` repository - but make sure to use `staging` branch.
+
+After that workflow completes, the new version should be available in the
drop-down list and stable links
+should be updated, also Fastly cache will be updated
+
## Prepare production Docker Image RC
Production Docker images should be manually prepared and pushed by the release
manager or another committer
@@ -816,57 +886,65 @@ docker pull apache/airflow:${VERSION}
breeze prod-image verify --image-name apache/airflow:${VERSION}
```
-## Publish documentation
+## Publish final documentation
Documentation is an essential part of the product and should be made available
to users.
-In our cases, documentation for the released versions is published in a
separate repository -
[`apache/airflow-site`](https://github.com/apache/airflow-site), but the
documentation source code and build tools are available in the `apache/airflow`
repository, so you have to coordinate between the two repositories to be able
to build the documentation.
+In our cases, documentation for the released versions is published in the
`live` S3 bucket, and the site is
+kept in a separate repository -
[`apache/airflow-site`](https://github.com/apache/airflow-site),
+but the documentation source code and build tools are available in the
`apache/airflow` repository, so
+you need to run several workflows to publish the documentation. More details
about it can be found in
+[Docs README](../docs/README.md) showing the architecture and workflows
including manual workflows for
+emergency cases.
-Documentation for providers can be found in the ``/docs/apache-airflow``
directory.
+We have two options publishing the documentation 1. Using breeze commands 2.
Manually using GitHub Actions.:
-- First, copy the airflow-site repository and set the environment variable
``AIRFLOW_SITE_DIRECTORY``.
+### Using breeze commands
- ```shell script
- git clone https://github.com/apache/airflow-site.git airflow-site
- cd airflow-site
- git checkout -b ${VERSION}-docs
- export AIRFLOW_SITE_DIRECTORY="$(pwd)"
- ```
+You can use the `breeze` command to publish the documentation.
+The command does the following:
-- Then you can go to the directory and build the necessary documentation
packages
+1. Triggers [Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
+2. Triggers workflow in apache/airflow-site to refresh
+3. Triggers S3 to GitHub Sync
- ```shell script
- cd "${AIRFLOW_REPO_ROOT}"
- breeze build-docs apache-airflow docker-stack --clean-build
- ```
+```shell script
+ breeze workflow-run publish-docs --ref <tag> --site-env <staging/live/auto>
+```
-- Now you can preview the documentation.
+The `--ref` parameter should be the tag of the final candidate you are
publishing.
- ```shell script
- ./docs/start_doc_server.sh
- ```
+The `--site-env` parameter should be set to `staging` for pre-release versions
or `live` for final releases. the default option is `auto`
+if the tag is rc it publishes to `staging` bucket, otherwise it publishes to
`live` bucket.
-- Copy the documentation to the ``airflow-site`` repository, create commit,
push changes, open a PR and merge it when the build is green.
+Other available parameters can be found with:
- ```shell script
- breeze release-management publish-docs apache-airflow docker-stack
- breeze release-management add-back-references apache-airflow
--airflow-site-directory "${AIRFLOW_SITE_DIRECTORY}"
- breeze sbom update-sbom-information --airflow-version ${VERSION}
--airflow-site-directory ${AIRFLOW_SITE_DIRECTORY} --force --all-combinations
--run-in-parallel
- cd "${AIRFLOW_SITE_DIRECTORY}"
- git add .
- git commit -m "Add documentation for Apache Airflow ${VERSION}"
- git push
- # and finally open a PR
- ```
+```shell
+breeze workflow-run publish-docs --help
+```
+
+### Manually using GitHub Actions
+
+There are two steps to publish the documentation:
+
+1. Publish the documentation to S3 bucket.
+
+The release manager publishes the documentation using GitHub Actions workflow
+[Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
By
+default `auto` selection should publish to the `live` bucket - based on
+the tag you use - pre-release tags go to staging. But you can also override it
and specify the destination
+manually to be `live` or `staging`.
-The `--run-in-parallel` switch allows to speed up SBOM generation
significantly, but it might take a lot
-of memory - if you are running into memory issues you can limit parallelism by
setting `--parallelism N`
-where N is a number of parallel `cdxgen` servers that should be started.
+After that step, the provider documentation should be available under the
https://airflow.apache.org/ URL
+(also linked directly from the PyPI packages) but stable links and drop-down
boxes should not be yet updated.
+That allows the Release Manager to verify if the documentation is published.
-## Wait and make sure documentation is published on the website before
proceeding
+2. Invalidate Fastly Cache, update version drop-down and stable links with the
new versions of the documentation.
-This is important as it takes time for the documentation to be published. You
should exercise some patient
-here before proceeding with the next steps.
+In order to do it, you need to run the [Build
docs](https://github.com/apache/airflow-site/actions/workflows/build.yml)
+workflow in `airflow-site` repository. Make sure to use `main` as the branch
to run the workflow.
+After that workflow completes, the new version should be available in the
drop-down list and stable links
+should be updated, also Fastly cache will be invalidated.
## Notify developers of release
@@ -1007,7 +1085,7 @@ This includes:
- For major/minor release, update version in `airflow/__init__.py` and
`docs/docker-stack/` to the next likely minor version release.
- Sync `RELEASE_NOTES.rst` (including deleting relevant `newsfragments`) and
`README.md` changes.
- Updating `Dockerfile` with the new version.
-- Updating `airflow_bug_report.yml` issue template in
`.github/ISSUE_TEMPLATE/` with the new version.
+- Updating `1-airflow_bug_report.yml` issue template in
`.github/ISSUE_TEMPLATE/` with the new version.
## Update default Airflow version in the helm chart
@@ -1046,7 +1124,7 @@ Clients can be found here:
### API Clients versioning policy
Clients and Core versioning are completely decoupled. Clients also follow
SemVer and are updated when core introduce changes relevant to the clients.
-Most of the time, if the [openapi
specification](https://github.com/apache/airflow/blob/main/airflow-core/src/airflow/api_fastapi/core_api/openapi/v1-rest-api-generated.yaml)
has
+Most of the time, if the [openapi
specification](https://github.com/apache/airflow/blob/main/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml)
has
changed, clients need to be released.
To determine if you should release API clients, you can run from the airflow
repository:
diff --git a/dev/README_RELEASE_PROVIDERS.md b/dev/README_RELEASE_PROVIDERS.md
index b98bfa5de1e..08492c7f2de 100644
--- a/dev/README_RELEASE_PROVIDERS.md
+++ b/dev/README_RELEASE_PROVIDERS.md
@@ -35,9 +35,9 @@
- [Build Provider distributions for SVN apache
upload](#build-provider-distributions-for-svn-apache-upload)
- [Build and sign the source and convenience
packages](#build-and-sign-the-source-and-convenience-packages)
- [Commit the source packages to Apache SVN
repo](#commit-the-source-packages-to-apache-svn-repo)
- - [Publish the Regular convenience package to
PyPI](#publish-the-regular-convenience-package-to-pypi)
+ - [Publish the Regular distributions to PyPI (release
candidates)](#publish-the-regular-distributions-to-pypi-release-candidates)
- [Add tags in git](#add-tags-in-git)
- - [Prepare documentation](#prepare-documentation)
+ - [Prepare documentation in Staging](#prepare-documentation-in-staging)
- [Prepare issue in GitHub to keep status of
testing](#prepare-issue-in-github-to-keep-status-of-testing)
- [Prepare voting email for Providers release
candidate](#prepare-voting-email-for-providers-release-candidate)
- [Verify the release candidate by PMC
members](#verify-the-release-candidate-by-pmc-members)
@@ -46,8 +46,8 @@
- [Summarize the voting for the Apache Airflow
release](#summarize-the-voting-for-the-apache-airflow-release)
- [Publish release to SVN](#publish-release-to-svn)
- [Publish the packages to PyPI](#publish-the-packages-to-pypi)
- - [Publish documentation prepared
before](#publish-documentation-prepared-before)
- [Add tags in git](#add-tags-in-git-1)
+ - [Publish documentation](#publish-documentation)
- [Update providers metadata](#update-providers-metadata)
- [Notify developers of release](#notify-developers-of-release)
- [Send announcements about security issues fixed in the
release](#send-announcements-about-security-issues-fixed-in-the-release)
@@ -415,7 +415,7 @@ svn rm file_name // repeate that for every file
svn commit -m "delete old providers"
```
-## Publish the Regular convenience package to PyPI
+## Publish the Regular distributions to PyPI (release candidates)
In order to publish release candidate to PyPI you just need to build and
release packages.
The packages should however contain the rcN suffix in the version file name
but not internally in the package,
@@ -486,127 +486,72 @@ If you want to disable this behaviour, set the env
**CLEAN_LOCAL_TAGS** to false
breeze release-management tag-providers
```
-## Prepare documentation
+## Prepare documentation in Staging
Documentation is an essential part of the product and should be made available
to users.
-In our cases, documentation for the released versions is published in a
separate repository -
-[`apache/airflow-site`](https://github.com/apache/airflow-site), but the
documentation source code
-and build tools are available in the `apache/airflow` repository, so you have
to coordinate between
-the two repositories to be able to build the documentation.
+In our cases, documentation for the released versions is published in the
staging S3 bucket, and the site is
+kept in a separate repository -
[`apache/airflow-site`](https://github.com/apache/airflow-site),
+but the documentation source code and build tools are available in the
`apache/airflow` repository, so
+you need to run several workflows to publish the documentation. More details
about it can be found in
+[Docs README](../docs/README.md) showing the architecture and workflows
including manual workflows for
+emergency cases.
-Documentation for providers can be found in the
`/docs/apache-airflow-providers` directory
-and the `/docs/apache-airflow-providers-*/` directory. The first directory
contains the package contents
-lists and should be updated every time a new version of Provider distributions
is released.
+We have two options publishing the documentation 1. Using breeze commands 2.
Manually using GitHub Actions.:
-- First, copy the airflow-site repository and set the environment variable
``AIRFLOW_SITE_DIRECTORY``.
+### Using breeze commands
-```shell script
-git clone https://github.com/apache/airflow-site.git airflow-site
-cd airflow-site
-export AIRFLOW_SITE_DIRECTORY="$(pwd -P)"
-```
-
-Note if this is not the first time you clone the repo make sure main branch is
rebased:
-
-```shell script
-cd "${AIRFLOW_SITE_DIRECTORY}"
-git checkout main
-git pull --rebase
-```
-
-- Then you can go to the directory and build the necessary documentation
packages
-
-```shell script
-cd "${AIRFLOW_REPO_ROOT}"
-breeze build-docs --clean-build apache-airflow-providers all-providers
--include-removed-providers
-```
-
-Usually when we release packages we also build documentation for the
"documentation-only" packages. This
-means that unless we release just few selected packages or if we need to
deliberately skip some packages
-we should release documentation for all Provider distributions and the above
command is the one to use.
-
-If we want to just release some providers you can release them using package
names:
-
-```shell script
-cd "${AIRFLOW_REPO_ROOT}"
-breeze build-docs apache-airflow-providers cncf.kubernetes sftp --clean-build
-```
-
-Alternatively, if you have set the environment variable: `DISTRIBUTIONS_LIST`
above, just run the command:
-
-```shell script
-cd "${AIRFLOW_REPO_ROOT}"
-breeze build-docs --clean-build
-```
+You can use the `breeze` command to publish the documentation.
+The command does the following:
-Or using `--distributions-list` argument:
-
-```shell script
-breeze build-docs --distributions-list PACKAGE1,PACKAGE2
-```
-
-- Now you can preview the documentation.
-
-```shell script
-./docs/start_doc_server.sh
-```
-
-If you encounter error like:
+1. Triggers [Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
+2. Triggers workflow in apache/airflow-site to refresh
+3. Triggers S3 to GitHub Sync
```shell script
-airflow git:(main) ./docs/start_doc_server.sh
-./docs/start_doc_server.sh: line 22: cd:
/Users/eladkal/PycharmProjects/airflow/docs/_build: No such file or directory
+ breeze workflow-run publish-docs --ref <tag> --site-env <staging/live/auto>
```
-That probably means that the doc folder is empty thus it can not build the doc
server.
-This indicates that previous step of building the docs did not work.
-
-- Copy the documentation to the ``airflow-site`` repository
-
-All providers (including overriding documentation for doc-only changes) - note
that publishing is
-way faster on multi-cpu machines when you are publishing multiple providers:
+The `--ref` parameter should be the tag of the release candidate you are
publishing.
+The `--site-env` parameter should be set to `staging` for pre-release versions
or `live` for final releases. the default option is `auto`
+if the tag is rc it publishes to `staging` bucket, otherwise it publishes to
`live` bucket.
-```shell script
-cd "${AIRFLOW_REPO_ROOT}"
-
-breeze release-management publish-docs apache-airflow-providers all-providers
--include-removed-providers \
- --override-versioned --run-in-parallel
+Other available parameters can be found with:
-breeze release-management add-back-references all-providers
+```shell
+breeze workflow-run publish-docs --help
```
-If you have providers as list of provider ids because you just released them
you can build them with
+### Manually using GitHub Actions
-```shell script
-cd "${AIRFLOW_REPO_ROOT}"
+There are two steps to publish the documentation:
-breeze release-management publish-docs amazon apache.beam google ....
-breeze release-management add-back-references all-providers
-```
+1. Publish the documentation to the staging S3 bucket.
-Alternatively, if you have set the environment variable: `DISTRIBUTIONS_LIST`
above, just run the command:
+The release manager publishes the documentation using GitHub Actions workflow
+[Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
-```shell script
-breeze release-management publish-docs
-breeze release-management add-back-references all-providers
-```
+You should specify the final tag to use to build the docs and list of
providers to publish
+(separated by spaces) or ``all-providers`` in case you want to publish all
providers
+(optionally you can exclude some of those providers). You should use `staging`
bucket to publish the release
+candidate documentation.
-Or using `--distributions-list` argument:
-
-```shell script
-breeze release-management publish-docs --distributions-list PACKAGE1,PACKAGE2
-breeze release-management add-back-references all-providers
-```
+After that step, the provider documentation should be available under the
http://airflow.staged.apache.org URL
+(also present in the PyPI packages) but stable links and drop-down boxes
should not be yet updated.
+2. Invalidate Fastly cache, update version drop-down and stable links with the
new versions of the documentation.
-Review the state of removed, suspended, new packages in
+Before doing it - review the state of removed, suspended, new packages in
[the docs
index](https://github.com/apache/airflow-site/blob/master/landing-pages/site/content/en/docs/_index.md):
+Make sure to use `staging` branch to run the workflow.
+
+There are few special considerations when the list of provider is updated.
- If you publish a new package, you must add it to the list of packages in the
index.
-- If there are changes to suspension or removal status of a package you must
move it appropriate section.
+- If there are changes to suspension or removal status of a package, you must
move it appropriate section.
-- Create the commit and push changes.
+- In case you need to make any changes - create the commit and push changes
and merge it to `staging` branch.
+ in [airflow-site](https://github.com/apache/airflow-site) repository.
```shell script
cd "${AIRFLOW_SITE_DIRECTORY}"
@@ -617,6 +562,15 @@ git commit -m "Add documentation for packages - $(date
"+%Y-%m-%d%n")"
git push --set-upstream origin "${branch}"
```
+Merging the PR with the index changes to `staging` will trigger site
publishing.
+
+If you do not need to merge a PR, you should manually run the
+[Build
docs](https://github.com/apache/airflow-site/actions/workflows/build.yml)
+workflow in `airflow-site` repository to refresh indexes and drop-downs.
+
+After that build from PR or workflow completes, the new version should be
available in the drop-down
+list and stable links should be updated, also Fastly cache will be invalidated.
+
## Prepare issue in GitHub to keep status of testing
Create a GitHub issue with the content generated via manual execution of the
command below. You will use
@@ -681,12 +635,20 @@ Make sure the packages are in
https://dist.apache.org/repos/dist/dev/airflow/pro
Send out a vote to the [email protected] mailing list. Here you can
prepare text of the
email.
-subject:
+```shell script
+export VOTE_DURATION_IN_HOURS=72
+export IS_SHORTEN_VOTE=$([ $VOTE_DURATION_IN_HOURS -ge 72 ] && echo "false" ||
echo "true")
+export SHORTEN_VOTE_TEXT="This is a shortened ($VOTE_DURATION_IN_HOURS hours
vote) as agreed by policy set it
https://lists.apache.org/thread/cv194w1fqqykrhswhmm54zy9gnnv6kgm"
+export VOTE_END_TIME=$(LANG=en_US.UTF-8 TZ=UTC date
-v+"${VOTE_DURATION_IN_HOURS}"H "+%B %d, %Y %H:%M %p")
+export RELEASE_MANAGER_NAME="Elad Kalif"
+export GITHUB_ISSUE_LINK="LINK_TO_GITHUB_ISSUE"
+```
+subject:
```shell script
cat <<EOF
-[VOTE] Airflow Providers prepared on $(date "+%B %d, %Y")
+[VOTE] Airflow Providers prepared on $(LANG=en_US.UTF-8 TZ=UTC date "+%B %d,
%Y")
EOF
```
@@ -695,8 +657,8 @@ cat <<EOF
Hey all,
I have just cut the new wave Airflow Providers packages. This email is calling
a vote on the release,
-which will last for 72 hours - which means that it will end on $(TZ=UTC date
-v+3d "+%B %d, %Y %H:%M %p" ) UTC and until 3 binding +1 votes have been
received.
-
+which will last for $VOTE_DURATION_IN_HOURS hours - which means that it will
end on $VOTE_END_TIME UTC and until 3 binding +1 votes have been received.
+$([ "$IS_SHORTEN_VOTE" = "true" ] && echo "${SHORTEN_VOTE_TEXT}" || echo "")
Consider this my (binding) +1.
@@ -735,7 +697,7 @@ This will allow us to rename the artifact without modifying
the artifact checksums when we actually release.
The status of testing the providers by the community is kept here:
-<TODO COPY LINK TO THE ISSUE CREATED>
+$GITHUB_ISSUE_LINK
The issue is also the easiest way to see important PRs included in the RC
candidates.
Detailed changelog for the providers will be published in the documentation
after the
@@ -746,7 +708,7 @@ You can find the RC packages in PyPI following these links:
<PASTE TWINE UPLOAD LINKS HERE. SORT THEM BEFORE!>
Cheers,
-<TODO: Your Name>
+$RELEASE_MANAGER_NAME
EOF
```
@@ -1253,21 +1215,6 @@ Copy links to updated packages, sort it alphabetically
and save it on the side.
* Again, confirm that the packages are available under the links printed.
-## Publish documentation prepared before
-
-Merge the PR that you prepared before with the documentation.
-
-If you decided to remove some packages from the release make sure to do amend
the commit in this way:
-
-* find the packages you removed in
`docs-archive/apache-airflow-providers-<PROVIDER>`
-* remove the latest version (the one you were releasing)
-* update `stable.txt` to the previous version
-* in the (unlikely) event you are removing first version of package:
- * remove whole `docs-archive/apache-airflow-providers-<PROVIDER>` folder
- * remove package from
`docs-archive/apache-airflow-providers/core-extensions/index.html` (2 places)
- * remove package from
`docs-archive/apache-airflow-providers/core-extensions/connections.html` (2
places)
- * remove package from
`docs-archive/apache-airflow-providers/core-extensions/extra-links.html` (2
places)
- * remove package from
`docs-archive/apache-airflow-providers/core-extensions/packages-ref.html` (5
places)
## Add tags in git
@@ -1283,12 +1230,103 @@ If you want to disable this behaviour, set the env
**CLEAN_LOCAL_TAGS** to false
breeze release-management tag-providers
```
+## Publish documentation
+
+Documentation is an essential part of the product and should be made available
to users.
+In our cases, documentation for the released versions is published in the
`live` S3 bucket, and the site is
+kept in a separate repository -
[`apache/airflow-site`](https://github.com/apache/airflow-site),
+but the documentation source code and build tools are available in the
`apache/airflow` repository, so
+you need to run several workflows to publish the documentation. More details
about it can be found in
+[Docs README](../docs/README.md) showing the architecture and workflows
including manual workflows for
+emergency cases.
+
+We have two options publishing the documentation 1. Using breeze commands 2.
Manually using GitHub Actions.:
+
+### Using breeze commands
+
+You can use the `breeze` command to publish the documentation.
+The command does the following:
+
+1. Triggers [Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
+2. Triggers workflow in apache/airflow-site to refresh
+3. Triggers S3 to GitHub Sync
+
+```shell script
+ breeze workflow-run publish-docs --ref <tag> --site-env <staging/live/auto>
+```
+
+The `--ref` parameter should be the tag of the final candidate you are
publishing.
+
+The `--site-env` parameter should be set to `staging` for pre-release versions
or `live` for final releases. the default option is `auto`
+if the tag is rc it publishes to `staging` bucket, otherwise it publishes to
`live` bucket.
+
+Other available parameters can be found with:
+
+```shell
+breeze workflow-run publish-docs --help
+```
+
+### Manually using GitHub Actions
+
+There are two steps to publish the documentation:
+
+1. Publish the documentation to the live S3 bucket.
+
+The release manager publishes the documentation using GitHub Actions workflow
+[Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
+
+You should specify the final tag to use to build the docs and list of
providers to publish
+(separated by spaces) or ``all-providers`` in case you want to publish all
providers
+(optionally you can exclude some of those providers).
+
+The release manager publishes the documentation using GitHub Actions workflow
+[Publish Docs to
S3](https://github.com/apache/airflow/actions/workflows/publish-docs-to-s3.yml).
+By default `auto` selection should publish to the `live` bucket - based on
+the tag you use - pre-release tags go to staging. But you can also override it
and specify the destination
+manually to be `live` or `staging`.
+
+After that step, the provider documentation should be available under the
http://airflow.apache.org URL
+(also present in the PyPI packages) but stable links and drop-down boxes
should not be yet updated.
+
+2. Invalidate Fastly cache, update version drop-down and stable links with the
new versions of the documentation.
+
+Before doing it - review the state of removed, suspended, new packages in
+[the docs
index](https://github.com/apache/airflow-site/blob/master/landing-pages/site/content/en/docs/_index.md):
+Make sure to use `main` branch to run the workflow.
+
+There are few special considerations when the list of provider is updated.
+
+- If you publish a new package, you must add it to the list of packages in the
index.
+- If there are changes to suspension or removal status of a package, you must
move it appropriate section.
+- In case you need to make any changes - create the commit and push changes
and merge it to `main` branch.
+ in [airflow-site](https://github.com/apache/airflow-site) repository.
+
+```shell script
+cd airflow-site
+export AIRFLOW_SITE_DIRECTORY="$(pwd -P)"
+cd "${AIRFLOW_SITE_DIRECTORY}"
+branch="add-documentation-$(date "+%Y-%m-%d%n")"
+git checkout -b "${branch}"
+git add .
+git commit -m "Add documentation for packages - $(date "+%Y-%m-%d%n")"
+git push --set-upstream origin "${branch}"
+```
+
+Merging the PR with the index changes to `main` will trigger site publishing.
+
+If you do not need to merge a PR, you should manually run the
+[Build
docs](https://github.com/apache/airflow-site/actions/workflows/build.yml)
+workflow in `airflow-site` repository to refresh indexes and drop-downs.
+
+After that build from PR or workflow completes, the new version should be
available in the drop-down
+list and stable links should be updated, also Fastly cache will be invalidated.
+
## Update providers metadata
```shell script
cd ${AIRFLOW_REPO_ROOT}
git checkout main
-git pull
+git pull apache main
current_date=$(date '+%Y-%m-%d%n')
branch="update-providers-metadata-${current_date}"
git checkout -b "${branch}"
diff --git a/dev/breeze/doc/09_release_management_tasks.rst
b/dev/breeze/doc/09_release_management_tasks.rst
index b83e6e17302..f6d7bbbebc3 100644
--- a/dev/breeze/doc/09_release_management_tasks.rst
+++ b/dev/breeze/doc/09_release_management_tasks.rst
@@ -33,21 +33,21 @@ Those are all of the available release management commands:
Airflow release commands
........................
-Running airflow release commands is part of the release procedure performed by
the release managers
+Running Airflow release commands is part of the release procedure performed by
the release managers
and it is described in detail in `dev <dev/README_RELEASE_AIRFLOW.md>`_ .
-Preparing airflow distributions
+Preparing Airflow distributions
""""""""""""""""""""""""""
-You can prepare airflow distributions using Breeze:
+You can prepare Airflow distributions using Breeze:
.. code-block:: bash
breeze release-management prepare-airflow-distributions
-This prepares airflow .whl package in the dist folder.
+This prepares Airflow .whl package in the dist folder.
-Again, you can specify optional ``--distribution-format`` flag to build
selected formats of airflow distributions,
+Again, you can specify optional ``--distribution-format`` flag to build
selected formats of Airflow distributions,
default is to build ``both`` type of distributions ``sdist`` and ``wheel``.
.. code-block:: bash
@@ -60,10 +60,10 @@ default is to build ``both`` type of distributions
``sdist`` and ``wheel``.
:alt: Breeze release-management prepare-airflow-distributions
-Preparing airflow tarball
+Preparing Airflow tarball
"""""""""""""""""""""""""
-You can prepare airflow source tarball using Breeze:
+You can prepare Airflow source tarball using Breeze:
.. code-block:: bash
@@ -127,10 +127,10 @@ When we prepare final release, we automate some of the
steps we need to do.
:width: 100%
:alt: Breeze release-management start-rc-process
-Generating airflow core Issue
+Generating Airflow core Issue
"""""""""""""""""""""""""
-You can use Breeze to generate a airflow core issue when you release new
airflow.
+You can use Breeze to generate a Airflow core issue when you release new
airflow.
.. image::
./images/output_release-management_generate-issue-content-providers.svg
:target:
https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_release-management_generate-issue-content-core.svg
@@ -266,7 +266,7 @@ The images are also aliased in dockerhub as appropriate.
Adding git tags for providers
"""""""""""""""""""""""""""""
-This command can be utilized to manage git tags for providers within the
airflow remote repository during provider releases.
+This command can be utilized to manage git tags for providers within the
Airflow remote repository during provider releases.
Sometimes in cases when there is a connectivity issue to GitHub, it might be
possible that local tags get created and lead to annoying errors.
The default behaviour would be to clean such local tags up.
@@ -376,7 +376,7 @@ Preparing providers
You can use Breeze to prepare providers.
The distributions are prepared in ``dist`` folder. Note, that this command
cleans up the ``dist`` folder
-before running, so you should run it before generating airflow package below
as it will be removed.
+before running, so you should run it before generating Airflow package below
as it will be removed.
The below example builds providers in the wheel format.
@@ -406,7 +406,7 @@ You can see all providers available by running this command:
Installing providers
""""""""""""""""""""
-In some cases we want to just see if the providers generated can be installed
with airflow without
+In some cases we want to just see if the providers generated can be installed
with Airflow without
verifying them. This happens automatically on CI for sdist pcackages but you
can also run it manually if you
just prepared providers and they are present in ``dist`` folder.
@@ -414,7 +414,7 @@ just prepared providers and they are present in ``dist``
folder.
breeze release-management install-provider-distributions
-You can also run the verification with an earlier airflow version to check for
compatibility.
+You can also run the verification with an earlier Airflow version to check for
compatibility.
.. code-block:: bash
@@ -438,7 +438,7 @@ just prepared providers and they are present in ``dist``
folder.
breeze release-management verify-provider-distributions
-You can also run the verification with an earlier airflow version to check for
compatibility.
+You can also run the verification with an earlier Airflow version to check for
compatibility.
.. code-block:: bash
@@ -455,7 +455,7 @@ Generating Providers Metadata
"""""""""""""""""""""""""""""
The release manager can generate providers metadata per provider version -
information about provider versions
-including the associated Airflow version for the provider version (i.e first
airflow version released after the
+including the associated Airflow version for the provider version (i.e first
Airflow version released after the
provider has been released) and date of the release of the provider version.
These are all of the available flags for the ``generate-providers-metadata``
command:
@@ -520,17 +520,17 @@ all or selected python version and single constraint mode
like this:
Constraints are generated separately for each python version and there are
separate constraints modes:
-* 'constraints' - those are constraints generated by matching the current
airflow version from sources
+* 'constraints' - those are constraints generated by matching the current
Airflow version from sources
and providers that are installed from PyPI. Those are constraints used by
the users who want to
- install airflow with pip.
+ install Airflow with pip.
* "constraints-source-providers" - those are constraints generated by using
providers installed from
current sources. While adding new providers their dependencies might change,
so this set of providers
- is the current set of the constraints for airflow and providers from the
current main sources.
+ is the current set of the constraints for Airflow and providers from the
current main sources.
Those providers are used by CI system to keep "stable" set of constraints.
* "constraints-no-providers" - those are constraints generated from only
Apache Airflow, without any
- providers. If you want to manage airflow separately and then add providers
individually, you can
+ providers. If you want to manage Airflow separately and then add providers
individually, you can
use those.
These are all available flags of ``generate-constraints`` command:
@@ -615,7 +615,7 @@ while publishing the documentation.
breeze release-management publish-docs --airflow-site-directory
You can also use shorthand names as arguments instead of using the full names
-for airflow providers. To find the short hand names, follow the instructions
in :ref:`generating_short_form_names`.
+for Airflow providers. To find the short hand names, follow the instructions
in :ref:`generating_short_form_names`.
The flag ``--airflow-site-directory`` takes the path of the cloned
``airflow-site``. The command will
not proceed if this is an invalid path.
@@ -635,7 +635,7 @@ Adding back referencing HTML for the documentation
To add back references to the documentation generated by ``build-docs`` in
Breeze to ``airflow-site``,
use the ``release-management add-back-references`` command. This is important
to support backward compatibility
-the airflow documentation.
+the Airflow documentation.
You have to specify which distributions you run it on. For example you can run
it for all providers:
@@ -690,7 +690,7 @@ Generating Provider requirements
In order to generate SBOM information for providers, we need to generate
requirements for them. This is
done by the ``generate-providers-requirements`` command. This command
generates requirements for the
-selected provider and python version, using the airflow version specified.
+selected provider and python version, using the Airflow version specified.
.. image:: ./images/output_sbom_generate-providers-requirements.svg
:target:
https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg
@@ -712,17 +712,17 @@ These are all of the available flags for the
``update-sbom-information`` command
:width: 100%
:alt: Breeze update sbom information
-Build all airflow images
+Build all Airflow images
""""""""""""""""""""""""
-In order to generate providers requirements, we need docker images with all
airflow versions pre-installed,
+In order to generate providers requirements, we need docker images with all
Airflow versions pre-installed,
such images are built with the ``build-all-airflow-images`` command.
-This command will build one docker image per python version, with all the
airflow versions >=2.0.0 compatible.
+This command will build one docker image per python version, with all the
Airflow versions >=2.0.0 compatible.
.. image:: ./images/output_sbom_build-all-airflow-images.svg
:target:
https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_sbom_build-all-airflow-images.svg
:width: 100%
- :alt: Breeze build all airflow images
+ :alt: Breeze build all Airflow images
Exporting SBOM information
@@ -741,16 +741,16 @@ properties of the dependencies. This is done by the
``export-dependency-informat
Next step: Follow the `Advanced Breeze topics
<10_advanced_breeze_topics.rst>`_ to
learn more about Breeze internals.
-Preparing airflow Task SDK distributions
+Preparing Airflow Task SDK distributions
"""""""""""""""""""""""""""""""""""
-You can prepare airflow distributions using Breeze:
+You can prepare Airflow distributions using Breeze:
.. code-block:: bash
breeze release-management prepare-task-sdk-distributions
-This prepares airflow Task SDK .whl package in the dist folder.
+This prepares Airflow Task SDK .whl package in the dist folder.
Again, you can specify optional ``--distribution-format`` flag to build
selected formats of the Task SDK distributions,
default is to build ``both`` type of distributions ``sdist`` and ``wheel``.
@@ -765,18 +765,18 @@ default is to build ``both`` type of distributions
``sdist`` and ``wheel``.
:alt: Breeze release-management prepare-task-sdk-distributions
-Preparing airflow ctl distributions
+Preparing Airflow ctl distributions
"""""""""""""""""""""""""""""""""""
-You can prepare airflow distributions using Breeze:
+You can prepare Airflow distributions using Breeze:
.. code-block:: bash
breeze release-management prepare-airflow-ctl-distributions
-This prepares airflow Task SDK .whl package in the dist folder.
+This prepares Airflow Task SDK .whl package in the dist folder.
-Again, you can specify optional ``--distribution-format`` flag to build
selected formats of the airflow ctl distributions,
+Again, you can specify optional ``--distribution-format`` flag to build
selected formats of the Airflow ctl distributions,
default is to build ``both`` type of distributions ``sdist`` and ``wheel``.
.. code-block:: bash
@@ -787,3 +787,92 @@ default is to build ``both`` type of distributions
``sdist`` and ``wheel``.
:target:
https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_release-management_prepare-airflow-ctl-distributions.svg
:width: 100%
:alt: Breeze release-management prepare-airflow-ctl-distributions
+
+Publishing the documentation to S3
+""""""""""""""""""""""""""""""""""
+
+To publish the documentation generated by ``build-docs`` in Breeze to ``S3``,
+use the ``release-management publish-docs-to-s3`` command:
+
+.. code-block:: bash
+
+ breeze release-management publish-docs-to-s3
+
+The documentation publish to S3 should be done after the ``breeze
release-management publish-docs`` command.
+Once documentation is available in ``docs-archive`` directory of airflow-site,
it can be published to S3.
+
+The publishing documentation to S3 consists of the following steps:
+
+.. code-block:: bash
+
+ breeze release-management publish-docs --source-dir-path <>
--destination-location <>
+
+Where ``--source-dir-path`` is a doc-archive location path and
``--destination-location`` is the S3 bucket path.
+
+.. code-block:: bash
+
+ breeze release-management publish-docs --source-dir-path
/User/pavan/airflow-site/docs-archive
+ --destination-location s3://airflow-docs/docs
+
+To exclude any documentation from publishing to S3, you can use the
``--exclude`` flag.
+
+.. code-block:: bash
+
+ breeze release-management publish-docs --source-dir-path
/User/pavan/airflow-site/docs-archive
+ --destination-location s3://airflow-docs/docs --exclude
"amazon,apache.kafka"
+
+To override the versioned directories while publishing the documentation to
S3, you can use the ``--overwrite`` flag.
+
+.. code-block:: bash
+
+ breeze release-management publish-docs --source-dir-path
/User/pavan/airflow-site/docs-archive
+ --destination-location s3://airflow-docs/docs --overwrite
+
+To check what documents will be published to S3, you can use the ``--dry-run``
flag.
+
+.. code-block:: bash
+
+ breeze release-management publish-docs --source-dir-path
/User/pavan/airflow-site/docs-archive
+ --destination-location s3://airflow-docs/docs --dry-run
+
+These are all available flags of ``release-management publish-docs-to-s3``
command:
+
+.. image:: ./images/output_release-management_publish-docs.svg
+ :target:
https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_release-management_publish-docs-to-s3.svg
+ :width: 100%
+ :alt: Breeze Publish documentation to S3
+
+
+Trigger GitHub Actions docs publish workflow
+"""""""""""""""""""""""""""""""""""""""""""""
+To trigger the GitHub Actions workflow that publishes the documentation to S3,
you can use the
+``breeze workflow-run publish-docs`` command.
+
+These are all available flags of ``workflow-run`` command:
+
+.. image:: ./images/output_workflow-run.svg
+ :target:
https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_workflow-run.svg
+ :width: 100%
+ :alt: Workflow run command
+
+
+.. code-block:: bash
+
+ breeze workflow-run publish-docs --ref <ref> --exclude-docs
<exclude-docs> --site-env <site-env> --refresh-site
--skip-write-to-stable-folder <docs_packages>
+
+ example:
+ breeze workflow-run publish-docs --ref providers-amazon/1.0.0 --site-env
live --refresh-site --skip-write-to-stable-folder amazon apache.kafka
+
+``--ref`` specifies the Git reference tag checkout and build docs.
+``--exclude-docs`` specifies the documentation packages to exclude from the
publish process.
+``--site-env`` specifies the environment to use for the site (e.g., auto,
live, staging). the default is auto, based on the ref it decides live or
staging.
+``--refresh-site`` specifies whether to refresh the site after publishing the
documentation. This triggers workflow on apache/airflow-site repository to
refresh the site.
+``--skip-write-to-stable-folder`` specifies the documentation packages to skip
writing to the stable folder.
+
+
+These are all available flags of ``workflow-run publish-docs`` command:
+
+.. image:: ./images/output_workflow-run_publish-docs.svg
+ :target:
https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
+ :width: 100%
+ :alt: Breeze workflow-run publish-docs
diff --git a/dev/breeze/doc/images/output-commands.svg
b/dev/breeze/doc/images/output-commands.svg
index 2d9668f5a21..030caaeb7d5 100644
--- a/dev/breeze/doc/images/output-commands.svg
+++ b/dev/breeze/doc/images/output-commands.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 2148.4"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 2172.7999999999997"
xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-help-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="2097.4" />
+ <rect x="0" y="0" width="1463.0" height="2121.7999999999997" />
</clipPath>
<clipPath id="breeze-help-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -300,9 +300,12 @@
<clipPath id="breeze-help-line-84">
<rect x="0" y="2051.1" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-help-line-85">
+ <rect x="0" y="2075.5" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="2146.4" rx="8"/><text
class="breeze-help-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Breeze commands</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="2170.8" rx="8"/><text
class="breeze-help-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Breeze commands</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -393,11 +396,12 @@
</text><text class="breeze-help-r5" x="0" y="1923.2" textLength="24.4"
clip-path="url(#breeze-help-line-78)">╭─</text><text class="breeze-help-r5"
x="24.4" y="1923.2" textLength="353.8"
clip-path="url(#breeze-help-line-78)"> Release management commands </text><text
class="breeze-help-r5" x="378.2" y="1923.2" textLength="1061.4"
clip-path="url(#breeze-help-line-78)">───────────────────────────────────────────────────────────────────────────────────────</text><text
clas [...]
</text><text class="breeze-help-r5" x="0" y="1947.6" textLength="12.2"
clip-path="url(#breeze-help-line-79)">│</text><text class="breeze-help-r4"
x="24.4" y="1947.6" textLength="280.6"
clip-path="url(#breeze-help-line-79)">release-management     </text><text
class="breeze-help-r1" x="329.4" y="1947.6" textLength="1110.2"
clip-path="url(#breeze-help-line-79)">Tools that release managers can use to prepare and manage
[...]
</text><text class="breeze-help-r5" x="0" y="1972" textLength="12.2"
clip-path="url(#breeze-help-line-80)">│</text><text class="breeze-help-r4"
x="24.4" y="1972" textLength="280.6"
clip-path="url(#breeze-help-line-80)">sbom                   </text><text
class="breeze-help-r1" x="329.4" y="1972" textLength="1110.2"
clip-path="url(#breeze-help-line-80)">Tools that release managers
[...]
-</text><text class="breeze-help-r5" x="0" y="1996.4" textLength="1464"
clip-path="url(#breeze-help-line-81)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-help-r1" x="1464" y="1996.4" textLength="12.2"
clip-path="url(#breeze-help-line-81)">
-</text><text class="breeze-help-r5" x="0" y="2020.8" textLength="24.4"
clip-path="url(#breeze-help-line-82)">╭─</text><text class="breeze-help-r5"
x="24.4" y="2020.8" textLength="195.2"
clip-path="url(#breeze-help-line-82)"> Other commands </text><text
class="breeze-help-r5" x="219.6" y="2020.8" textLength="1220"
clip-path="url(#breeze-help-line-82)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
class="bree [...]
-</text><text class="breeze-help-r5" x="0" y="2045.2" textLength="12.2"
clip-path="url(#breeze-help-line-83)">│</text><text class="breeze-help-r4"
x="24.4" y="2045.2" textLength="122"
clip-path="url(#breeze-help-line-83)">setup     </text><text
class="breeze-help-r1" x="170.8" y="2045.2" textLength="1268.8"
clip-path="url(#breeze-help-line-83)">Tools that developers can use to configure Breeze      &
[...]
-</text><text class="breeze-help-r5" x="0" y="2069.6" textLength="12.2"
clip-path="url(#breeze-help-line-84)">│</text><text class="breeze-help-r4"
x="24.4" y="2069.6" textLength="122"
clip-path="url(#breeze-help-line-84)">ci        </text><text
class="breeze-help-r1" x="170.8" y="2069.6" textLength="1268.8"
clip-path="url(#breeze-help-line-84)">Tools that CI workflows use to cleanup/manage CI environment 
[...]
-</text><text class="breeze-help-r5" x="0" y="2094" textLength="1464"
clip-path="url(#breeze-help-line-85)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-help-r1" x="1464" y="2094" textLength="12.2"
clip-path="url(#breeze-help-line-85)">
+</text><text class="breeze-help-r5" x="0" y="1996.4" textLength="12.2"
clip-path="url(#breeze-help-line-81)">│</text><text class="breeze-help-r4"
x="24.4" y="1996.4" textLength="280.6"
clip-path="url(#breeze-help-line-81)">workflow-run           </text><text
class="breeze-help-r1" x="329.4" y="1996.4" textLength="1110.2"
clip-path="url(#breeze-help-line-81)">Tools to manage Airflow repository workflows &
[...]
+</text><text class="breeze-help-r5" x="0" y="2020.8" textLength="1464"
clip-path="url(#breeze-help-line-82)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-help-r1" x="1464" y="2020.8" textLength="12.2"
clip-path="url(#breeze-help-line-82)">
+</text><text class="breeze-help-r5" x="0" y="2045.2" textLength="24.4"
clip-path="url(#breeze-help-line-83)">╭─</text><text class="breeze-help-r5"
x="24.4" y="2045.2" textLength="195.2"
clip-path="url(#breeze-help-line-83)"> Other commands </text><text
class="breeze-help-r5" x="219.6" y="2045.2" textLength="1220"
clip-path="url(#breeze-help-line-83)">────────────────────────────────────────────────────────────────────────────────────────────────────</text><text
class="bree [...]
+</text><text class="breeze-help-r5" x="0" y="2069.6" textLength="12.2"
clip-path="url(#breeze-help-line-84)">│</text><text class="breeze-help-r4"
x="24.4" y="2069.6" textLength="122"
clip-path="url(#breeze-help-line-84)">setup     </text><text
class="breeze-help-r1" x="170.8" y="2069.6" textLength="1268.8"
clip-path="url(#breeze-help-line-84)">Tools that developers can use to configure Breeze      &
[...]
+</text><text class="breeze-help-r5" x="0" y="2094" textLength="12.2"
clip-path="url(#breeze-help-line-85)">│</text><text class="breeze-help-r4"
x="24.4" y="2094" textLength="122"
clip-path="url(#breeze-help-line-85)">ci        </text><text
class="breeze-help-r1" x="170.8" y="2094" textLength="1268.8"
clip-path="url(#breeze-help-line-85)">Tools that CI workflows use to cleanup/manage CI environment  
[...]
+</text><text class="breeze-help-r5" x="0" y="2118.4" textLength="1464"
clip-path="url(#breeze-help-line-86)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-help-r1" x="1464" y="2118.4" textLength="12.2"
clip-path="url(#breeze-help-line-86)">
</text>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg
b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg
index c61da6940de..118c0c3d4e2 100644
--- a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg
+++ b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg
@@ -215,7 +215,7 @@
</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0"
y="800.8" textLength="12.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-32)">│</text><text
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="800.8"
textLength="1256.6"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-32)">testing:airflow-ctl-tests | testing:core-integration-tests | testing:core-tests |         
[...]
</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0"
y="825.2" textLength="12.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-33)">│</text><text
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="825.2"
textLength="1256.6"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-33)">testing:docker-compose-tests | testing:helm-tests | testing:providers-integration-tests |       
[...]
</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0"
y="849.6" textLength="12.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-34)">│</text><text
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="849.6"
textLength="1256.6"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-34)">testing:providers-tests | testing:python-api-client-tests | testing:system-tests |        
[...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="874"
textLength="12.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">│</text><text
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="874"
textLength="1256.6"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">testing:task-sdk-tests)                       &#
[...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="874"
textLength="12.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">│</text><text
class="breeze-setup-check-all-params-in-groups-r6" x="183" y="874"
textLength="1256.6"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">testing:task-sdk-tests | workflow-run | workflow-run:publish-docs)             
[...]
</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0"
y="898.4" textLength="1464"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-36)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-setup-check-all-params-in-groups-r1" x="1464" y="898.4"
textLength="12.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-36)">
</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0"
y="922.8" textLength="24.4"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-37)">╭─</text><text
class="breeze-setup-check-all-params-in-groups-r5" x="24.4" y="922.8"
textLength="195.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-37)"> Common options </text><text
class="breeze-setup-check-all-params-in-groups-r5" x="219.6" y="922.8"
textLength="1220" clip-path="url(#breeze-se [...]
</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0"
y="947.2" textLength="12.2"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-38)">│</text><text
class="breeze-setup-check-all-params-in-groups-r4" x="24.4" y="947.2"
textLength="109.8"
clip-path="url(#breeze-setup-check-all-params-in-groups-line-38)">--verbose</text><text
class="breeze-setup-check-all-params-in-groups-r7" x="158.6" y="947.2"
textLength="24.4" clip-path="url(#breeze-setup-check-all-params-in [...]
diff --git a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt
b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt
index f28b4e6f51e..2b4291e68d2 100644
--- a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt
+++ b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt
@@ -1 +1 @@
-41e8d5cb0d997969ca1b6b079446488e
+281648f2acfd40a2d6c72d8b935f7211
diff --git a/dev/breeze/doc/images/output_setup_regenerate-command-images.svg
b/dev/breeze/doc/images/output_setup_regenerate-command-images.svg
index 0ee7112ff35..b810ff7beab 100644
--- a/dev/breeze/doc/images/output_setup_regenerate-command-images.svg
+++ b/dev/breeze/doc/images/output_setup_regenerate-command-images.svg
@@ -233,7 +233,7 @@
</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="874"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-35)">│</text><text
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="874"
textLength="1220"
clip-path="url(#breeze-setup-regenerate-command-images-line-35)">static-checks | testing | testing:airflow-ctl-tests | testing:core-integration-tests |       
[...]
</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="898.4"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-36)">│</text><text
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="898.4"
textLength="1220"
clip-path="url(#breeze-setup-regenerate-command-images-line-36)">testing:core-tests | testing:docker-compose-tests | testing:helm-tests |           
[...]
</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="922.8"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-37)">│</text><text
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="922.8"
textLength="1220"
clip-path="url(#breeze-setup-regenerate-command-images-line-37)">testing:providers-integration-tests | testing:providers-tests | testing:python-api-client-tests |   </text><text
class="bre [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="947.2"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-38)">│</text><text
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="947.2"
textLength="1220"
clip-path="url(#breeze-setup-regenerate-command-images-line-38)">testing:system-tests | testing:task-sdk-tests)                  
[...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="947.2"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-38)">│</text><text
class="breeze-setup-regenerate-command-images-r6" x="219.6" y="947.2"
textLength="1220"
clip-path="url(#breeze-setup-regenerate-command-images-line-38)">testing:system-tests | testing:task-sdk-tests | workflow-run | workflow-run:publish-docs)       &#
[...]
</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="971.6"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-39)">│</text><text
class="breeze-setup-regenerate-command-images-r4" x="24.4" y="971.6"
textLength="146.4"
clip-path="url(#breeze-setup-regenerate-command-images-line-39)">--check-only</text><text
class="breeze-setup-regenerate-command-images-r1" x="219.6" y="971.6"
textLength="1220" clip-path="url(#breeze-setup-regenerate-command-im [...]
</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="996"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-40)">│</text><text
class="breeze-setup-regenerate-command-images-r1" x="219.6" y="996"
textLength="170.8"
clip-path="url(#breeze-setup-regenerate-command-images-line-40)">together with </text><text
class="breeze-setup-regenerate-command-images-r4" x="390.4" y="996"
textLength="109.8" clip-path="url(#breeze-setup-regenerate-co [...]
</text><text class="breeze-setup-regenerate-command-images-r5" x="0"
y="1020.4" textLength="1464"
clip-path="url(#breeze-setup-regenerate-command-images-line-41)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-setup-regenerate-command-images-r1" x="1464" y="1020.4"
textLength="12.2"
clip-path="url(#breeze-setup-regenerate-command-images-line-41)">
diff --git a/dev/breeze/doc/images/output_setup_regenerate-command-images.txt
b/dev/breeze/doc/images/output_setup_regenerate-command-images.txt
index 825aefbbf35..f48a094c49d 100644
--- a/dev/breeze/doc/images/output_setup_regenerate-command-images.txt
+++ b/dev/breeze/doc/images/output_setup_regenerate-command-images.txt
@@ -1 +1 @@
-170493c744c7a901f3f1c4ffb1e1c89b
+5661481e019525eae03f87ee1efeb6ee
diff --git a/dev/breeze/doc/images/output_workflow-run.svg
b/dev/breeze/doc/images/output_workflow-run.svg
new file mode 100644
index 00000000000..af211f19a8e
--- /dev/null
+++ b/dev/breeze/doc/images/output_workflow-run.svg
@@ -0,0 +1,103 @@
+<svg class="rich-terminal" viewBox="0 0 1482 318.4"
xmlns="http://www.w3.org/2000/svg">
+ <!-- Generated with Rich https://www.textualize.io -->
+ <style>
+
+ @font-face {
+ font-family: "Fira Code";
+ src: local("FiraCode-Regular"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff");
+ font-style: normal;
+ font-weight: 400;
+ }
+ @font-face {
+ font-family: "Fira Code";
+ src: local("FiraCode-Bold"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2")
format("woff2"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff")
format("woff");
+ font-style: bold;
+ font-weight: 700;
+ }
+
+ .breeze-workflow-run-matrix {
+ font-family: Fira Code, monospace;
+ font-size: 20px;
+ line-height: 24.4px;
+ font-variant-east-asian: full-width;
+ }
+
+ .breeze-workflow-run-title {
+ font-size: 18px;
+ font-weight: bold;
+ font-family: arial;
+ }
+
+ .breeze-workflow-run-r1 { fill: #c5c8c6 }
+.breeze-workflow-run-r2 { fill: #d0b344 }
+.breeze-workflow-run-r3 { fill: #c5c8c6;font-weight: bold }
+.breeze-workflow-run-r4 { fill: #68a0b3;font-weight: bold }
+.breeze-workflow-run-r5 { fill: #868887 }
+.breeze-workflow-run-r6 { fill: #98a84b;font-weight: bold }
+ </style>
+
+ <defs>
+ <clipPath id="breeze-workflow-run-clip-terminal">
+ <rect x="0" y="0" width="1463.0" height="267.4" />
+ </clipPath>
+ <clipPath id="breeze-workflow-run-line-0">
+ <rect x="0" y="1.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-1">
+ <rect x="0" y="25.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-2">
+ <rect x="0" y="50.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-3">
+ <rect x="0" y="74.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-4">
+ <rect x="0" y="99.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-5">
+ <rect x="0" y="123.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-6">
+ <rect x="0" y="147.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-7">
+ <rect x="0" y="172.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-8">
+ <rect x="0" y="196.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-line-9">
+ <rect x="0" y="221.1" width="1464" height="24.65"/>
+ </clipPath>
+ </defs>
+
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="316.4" rx="8"/><text
class="breeze-workflow-run-title" fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: workflow-run</text>
+ <g transform="translate(26,22)">
+ <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+ <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+ <circle cx="44" cy="0" r="7" fill="#28c840"/>
+ </g>
+
+ <g transform="translate(9, 41)"
clip-path="url(#breeze-workflow-run-clip-terminal)">
+
+ <g class="breeze-workflow-run-matrix">
+ <text class="breeze-workflow-run-r1" x="1464" y="20" textLength="12.2"
clip-path="url(#breeze-workflow-run-line-0)">
+</text><text class="breeze-workflow-run-r2" x="12.2" y="44.4"
textLength="73.2"
clip-path="url(#breeze-workflow-run-line-1)">Usage:</text><text
class="breeze-workflow-run-r3" x="97.6" y="44.4" textLength="231.8"
clip-path="url(#breeze-workflow-run-line-1)">breeze workflow-run</text><text
class="breeze-workflow-run-r1" x="341.6" y="44.4" textLength="12.2"
clip-path="url(#breeze-workflow-run-line-1)">[</text><text
class="breeze-workflow-run-r4" x="353.8" y="44.4" textLength="85.4" cli [...]
+</text><text class="breeze-workflow-run-r1" x="1464" y="68.8"
textLength="12.2" clip-path="url(#breeze-workflow-run-line-2)">
+</text><text class="breeze-workflow-run-r1" x="12.2" y="93.2"
textLength="536.8"
clip-path="url(#breeze-workflow-run-line-3)">Tools to manage Airflow repository workflows</text><text
class="breeze-workflow-run-r1" x="1464" y="93.2" textLength="12.2"
clip-path="url(#breeze-workflow-run-line-3)">
+</text><text class="breeze-workflow-run-r1" x="1464" y="117.6"
textLength="12.2" clip-path="url(#breeze-workflow-run-line-4)">
+</text><text class="breeze-workflow-run-r5" x="0" y="142" textLength="24.4"
clip-path="url(#breeze-workflow-run-line-5)">╭─</text><text
class="breeze-workflow-run-r5" x="24.4" y="142" textLength="195.2"
clip-path="url(#breeze-workflow-run-line-5)"> Common options </text><text
class="breeze-workflow-run-r5" x="219.6" y="142" textLength="1220"
clip-path="url(#breeze-workflow-run-line-5)">────────────────────────────────────────────────────────────────────────────────────────
[...]
+</text><text class="breeze-workflow-run-r5" x="0" y="166.4" textLength="12.2"
clip-path="url(#breeze-workflow-run-line-6)">│</text><text
class="breeze-workflow-run-r4" x="24.4" y="166.4" textLength="73.2"
clip-path="url(#breeze-workflow-run-line-6)">--help</text><text
class="breeze-workflow-run-r6" x="122" y="166.4" textLength="24.4"
clip-path="url(#breeze-workflow-run-line-6)">-h</text><text
class="breeze-workflow-run-r1" x="170.8" y="166.4" textLength="329.4"
clip-path="url(#breeze-wor [...]
+</text><text class="breeze-workflow-run-r5" x="0" y="190.8" textLength="1464"
clip-path="url(#breeze-workflow-run-line-7)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-workflow-run-r1" x="1464" y="190.8" textLength="12.2"
clip-path="url(#breeze-workflow-run-line-7)">
+</text><text class="breeze-workflow-run-r5" x="0" y="215.2" textLength="24.4"
clip-path="url(#breeze-workflow-run-line-8)">╭─</text><text
class="breeze-workflow-run-r5" x="24.4" y="215.2" textLength="512.4"
clip-path="url(#breeze-workflow-run-line-8)"> Airflow github actions workflow commands </text><text
class="breeze-workflow-run-r5" x="536.8" y="215.2" textLength="902.8"
clip-path="url(#breeze-workflow-run-line-8)">────────────────────────────────────────
[...]
+</text><text class="breeze-workflow-run-r5" x="0" y="239.6" textLength="12.2"
clip-path="url(#breeze-workflow-run-line-9)">│</text><text
class="breeze-workflow-run-r4" x="24.4" y="239.6" textLength="366"
clip-path="url(#breeze-workflow-run-line-9)">publish-docs                  </text><text
class="breeze-workflow-run-r1" x="414.8" y="239.6" textLength="1024.8"
clip-path="url(#breeze-workflow-run-lin [...]
+</text><text class="breeze-workflow-run-r5" x="0" y="264" textLength="1464"
clip-path="url(#breeze-workflow-run-line-10)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-workflow-run-r1" x="1464" y="264" textLength="12.2"
clip-path="url(#breeze-workflow-run-line-10)">
+</text>
+ </g>
+ </g>
+</svg>
diff --git a/dev/breeze/doc/images/output_workflow-run.txt
b/dev/breeze/doc/images/output_workflow-run.txt
new file mode 100644
index 00000000000..7c0345e43fc
--- /dev/null
+++ b/dev/breeze/doc/images/output_workflow-run.txt
@@ -0,0 +1 @@
+bff0ef03c469cfda50f0383a9d1986aa
diff --git a/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
b/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
new file mode 100644
index 00000000000..135199a1465
--- /dev/null
+++ b/dev/breeze/doc/images/output_workflow-run_publish-docs.svg
@@ -0,0 +1,166 @@
+<svg class="rich-terminal" viewBox="0 0 1482 684.4"
xmlns="http://www.w3.org/2000/svg">
+ <!-- Generated with Rich https://www.textualize.io -->
+ <style>
+
+ @font-face {
+ font-family: "Fira Code";
+ src: local("FiraCode-Regular"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2")
format("woff2"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff")
format("woff");
+ font-style: normal;
+ font-weight: 400;
+ }
+ @font-face {
+ font-family: "Fira Code";
+ src: local("FiraCode-Bold"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2")
format("woff2"),
+
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff")
format("woff");
+ font-style: bold;
+ font-weight: 700;
+ }
+
+ .breeze-workflow-run-publish-docs-matrix {
+ font-family: Fira Code, monospace;
+ font-size: 20px;
+ line-height: 24.4px;
+ font-variant-east-asian: full-width;
+ }
+
+ .breeze-workflow-run-publish-docs-title {
+ font-size: 18px;
+ font-weight: bold;
+ font-family: arial;
+ }
+
+ .breeze-workflow-run-publish-docs-r1 { fill: #c5c8c6 }
+.breeze-workflow-run-publish-docs-r2 { fill: #d0b344 }
+.breeze-workflow-run-publish-docs-r3 { fill: #c5c8c6;font-weight: bold }
+.breeze-workflow-run-publish-docs-r4 { fill: #68a0b3;font-weight: bold }
+.breeze-workflow-run-publish-docs-r5 { fill: #868887 }
+.breeze-workflow-run-publish-docs-r6 { fill: #cc555a }
+.breeze-workflow-run-publish-docs-r7 { fill: #8d7b39 }
+.breeze-workflow-run-publish-docs-r8 { fill: #8a4346 }
+.breeze-workflow-run-publish-docs-r9 { fill: #98a84b;font-weight: bold }
+ </style>
+
+ <defs>
+ <clipPath id="breeze-workflow-run-publish-docs-clip-terminal">
+ <rect x="0" y="0" width="1463.0" height="633.4" />
+ </clipPath>
+ <clipPath id="breeze-workflow-run-publish-docs-line-0">
+ <rect x="0" y="1.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-1">
+ <rect x="0" y="25.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-2">
+ <rect x="0" y="50.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-3">
+ <rect x="0" y="74.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-4">
+ <rect x="0" y="99.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-5">
+ <rect x="0" y="123.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-6">
+ <rect x="0" y="147.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-7">
+ <rect x="0" y="172.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-8">
+ <rect x="0" y="196.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-9">
+ <rect x="0" y="221.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-10">
+ <rect x="0" y="245.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-11">
+ <rect x="0" y="269.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-12">
+ <rect x="0" y="294.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-13">
+ <rect x="0" y="318.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-14">
+ <rect x="0" y="343.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-15">
+ <rect x="0" y="367.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-16">
+ <rect x="0" y="391.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-17">
+ <rect x="0" y="416.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-18">
+ <rect x="0" y="440.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-19">
+ <rect x="0" y="465.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-20">
+ <rect x="0" y="489.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-21">
+ <rect x="0" y="513.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-22">
+ <rect x="0" y="538.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-23">
+ <rect x="0" y="562.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="breeze-workflow-run-publish-docs-line-24">
+ <rect x="0" y="587.1" width="1464" height="24.65"/>
+ </clipPath>
+ </defs>
+
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="682.4" rx="8"/><text
class="breeze-workflow-run-publish-docs-title" fill="#c5c8c6"
text-anchor="middle" x="740"
y="27">Command: workflow-run publish-docs</text>
+ <g transform="translate(26,22)">
+ <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+ <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+ <circle cx="44" cy="0" r="7" fill="#28c840"/>
+ </g>
+
+ <g transform="translate(9, 41)"
clip-path="url(#breeze-workflow-run-publish-docs-clip-terminal)">
+
+ <g class="breeze-workflow-run-publish-docs-matrix">
+ <text class="breeze-workflow-run-publish-docs-r1" x="1464" y="20"
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-0)">
+</text><text class="breeze-workflow-run-publish-docs-r2" x="12.2" y="44.4"
textLength="1439.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-1)">Usage:                                                       
[...]
+</text><text class="breeze-workflow-run-publish-docs-r3" x="12.2" y="68.8"
textLength="1439.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-2)">breeze workflow-run publish-docs                                                 
[...]
+</text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="93.2"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-3)">[</text><text
class="breeze-workflow-run-publish-docs-r4" x="24.4" y="93.2" textLength="85.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-3)">OPTIONS</text><text
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="93.2"
textLength="36.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-3)">] [</text><text
class="br [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="117.6"
textLength="73.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-4)">apache</text><text
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="117.6"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-4)">.</text><text
class="breeze-workflow-run-publish-docs-r4" x="97.6" y="117.6"
textLength="109.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-4)">cassandra</text><text
class= [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="142"
textLength="73.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-5)">apache</text><text
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="142" textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-5)">.</text><text
class="breeze-workflow-run-publish-docs-r4" x="97.6" y="142" textLength="73.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-5)">impala</text><text
class="breeze-wo [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="166.4"
textLength="97.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-6)">arangodb</text><text
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="166.4"
textLength="36.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-6)"> | </text><text
class="breeze-workflow-run-publish-docs-r4" x="146.4" y="166.4"
textLength="61"
clip-path="url(#breeze-workflow-run-publish-docs-line-6)">asana</text><te [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="190.8"
textLength="73.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-7)">common</text><text
class="breeze-workflow-run-publish-docs-r1" x="85.4" y="190.8"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-7)">.</text><text
class="breeze-workflow-run-publish-docs-r4" x="97.6" y="190.8"
textLength="109.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-7)">messaging</text><text
class= [...]
+</text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="215.2"
textLength="24.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-8)">| </text><text
class="breeze-workflow-run-publish-docs-r4" x="36.6" y="215.2"
textLength="158.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-8)">elasticsearch</text><text
class="breeze-workflow-run-publish-docs-r1" x="195.2" y="215.2"
textLength="36.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-8)"> | < [...]
+</text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="239.6"
textLength="24.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">| </text><text
class="breeze-workflow-run-publish-docs-r4" x="36.6" y="239.6"
textLength="97.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-9)">influxdb</text><text
class="breeze-workflow-run-publish-docs-r1" x="134.2" y="239.6"
textLength="36.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-9)"> | </text>
[...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="264"
textLength="61"
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">neo4j</text><text
class="breeze-workflow-run-publish-docs-r1" x="73.2" y="264" textLength="36.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-10)"> | </text><text
class="breeze-workflow-run-publish-docs-r4" x="109.8" y="264"
textLength="48.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-10)">odbc</text><text
class [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="288.4"
textLength="97.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">pinecone</text><text
class="breeze-workflow-run-publish-docs-r1" x="109.8" y="288.4"
textLength="36.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-11)"> | </text><text
class="breeze-workflow-run-publish-docs-r4" x="146.4" y="288.4"
textLength="97.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-11)">postgres</ [...]
+</text><text class="breeze-workflow-run-publish-docs-r4" x="12.2" y="312.8"
textLength="48.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">smtp</text><text
class="breeze-workflow-run-publish-docs-r1" x="61" y="312.8" textLength="36.6"
clip-path="url(#breeze-workflow-run-publish-docs-line-12)"> | </text><text
class="breeze-workflow-run-publish-docs-r4" x="97.6" y="312.8"
textLength="109.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-12)">snowflake</text><
[...]
+</text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="337.2"
textLength="24.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">| </text><text
class="breeze-workflow-run-publish-docs-r4" x="36.6" y="337.2"
textLength="85.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">zendesk</text><text
class="breeze-workflow-run-publish-docs-r1" x="122" y="337.2"
textLength="1329.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-13)">]...  &#
[...]
+</text><text class="breeze-workflow-run-publish-docs-r1" x="1464" y="361.6"
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-14)">
+</text><text class="breeze-workflow-run-publish-docs-r1" x="12.2" y="386"
textLength="427"
clip-path="url(#breeze-workflow-run-publish-docs-line-15)">Trigger publish docs to S3 workflow</text><text
class="breeze-workflow-run-publish-docs-r1" x="1464" y="386" textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-15)">
+</text><text class="breeze-workflow-run-publish-docs-r1" x="1464" y="410.4"
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-16)">
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="434.8"
textLength="24.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-17)">╭─</text><text
class="breeze-workflow-run-publish-docs-r5" x="24.4" y="434.8"
textLength="378.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-17)"> Trigger publish docs workflow </text><text
class="breeze-workflow-run-publish-docs-r5" x="402.6" y="434.8"
textLength="1037" clip-path="url(#breeze-workflow-run [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="459.2"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-18)">│</text><text
class="breeze-workflow-run-publish-docs-r6" x="24.4" y="459.2"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-18)">*</text><text
class="breeze-workflow-run-publish-docs-r4" x="61" y="459.2" textLength="61"
clip-path="url(#breeze-workflow-run-publish-docs-line-18)">--ref</text><text
class="breeze-workfl [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="483.6"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-19)">│</text><text
class="breeze-workflow-run-publish-docs-r4" x="61" y="483.6" textLength="170.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-19)">--exclude-docs</text><text
class="breeze-workflow-run-publish-docs-r1" x="463.6" y="483.6"
textLength="805.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-19)">Comma separated
[...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="508"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-20)">│</text><text
class="breeze-workflow-run-publish-docs-r4" x="61" y="508" textLength="122"
clip-path="url(#breeze-workflow-run-publish-docs-line-20)">--site-env</text><text
class="breeze-workflow-run-publish-docs-r1" x="463.6" y="508" textLength="671"
clip-path="url(#breeze-workflow-run-publish-docs-line-20)">S3 bucket to which&
[...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="532.4"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-21)">│</text><text
class="breeze-workflow-run-publish-docs-r4" x="61" y="532.4" textLength="353.8"
clip-path="url(#breeze-workflow-run-publish-docs-line-21)">--skip-write-to-stable-folder</text><text
class="breeze-workflow-run-publish-docs-r1" x="463.6" y="532.4"
textLength="366"
clip-path="url(#breeze-workflow-run-publish-docs-line-21)">Skip [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="556.8"
textLength="1464"
clip-path="url(#breeze-workflow-run-publish-docs-line-22)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-workflow-run-publish-docs-r1" x="1464" y="556.8"
textLength="12.2" clip-path="url(#breeze-workflow-run-publish-docs-line-22)">
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="581.2"
textLength="24.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-23)">╭─</text><text
class="breeze-workflow-run-publish-docs-r5" x="24.4" y="581.2"
textLength="195.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-23)"> Common options </text><text
class="breeze-workflow-run-publish-docs-r5" x="219.6" y="581.2"
textLength="1220" clip-path="url(#breeze-workflow-run-publish-docs-line-23)">─
[...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="605.6"
textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-24)">│</text><text
class="breeze-workflow-run-publish-docs-r4" x="24.4" y="605.6"
textLength="73.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-24)">--help</text><text
class="breeze-workflow-run-publish-docs-r9" x="122" y="605.6" textLength="24.4"
clip-path="url(#breeze-workflow-run-publish-docs-line-24)">-h</text><text
class="breeze-w [...]
+</text><text class="breeze-workflow-run-publish-docs-r5" x="0" y="630"
textLength="1464"
clip-path="url(#breeze-workflow-run-publish-docs-line-25)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-workflow-run-publish-docs-r1" x="1464" y="630" textLength="12.2"
clip-path="url(#breeze-workflow-run-publish-docs-line-25)">
+</text>
+ </g>
+ </g>
+</svg>
diff --git a/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
b/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
new file mode 100644
index 00000000000..ccebd4389d3
--- /dev/null
+++ b/dev/breeze/doc/images/output_workflow-run_publish-docs.txt
@@ -0,0 +1 @@
+9ee2e8e8aa91886504c2d859b4e6bc49
diff --git a/dev/breeze/src/airflow_breeze/breeze.py
b/dev/breeze/src/airflow_breeze/breeze.py
index ed651457009..fab25baba1d 100755
--- a/dev/breeze/src/airflow_breeze/breeze.py
+++ b/dev/breeze/src/airflow_breeze/breeze.py
@@ -18,6 +18,7 @@
from __future__ import annotations
from airflow_breeze.commands.main_command import main
+from airflow_breeze.commands.workflow_commands import workflow_run
from airflow_breeze.utils.path_utils import (
create_directories_and_files,
find_airflow_root_path_to_operate_on,
@@ -50,6 +51,7 @@ main.add_command(prod_image)
main.add_command(setup)
main.add_command(release_management)
main.add_command(sbom)
+main.add_command(workflow_run)
if __name__ == "__main__":
main()
diff --git a/dev/breeze/src/airflow_breeze/commands/workflow_commands.py
b/dev/breeze/src/airflow_breeze/commands/workflow_commands.py
new file mode 100644
index 00000000000..5f1225ad93f
--- /dev/null
+++ b/dev/breeze/src/airflow_breeze/commands/workflow_commands.py
@@ -0,0 +1,155 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import json
+import re
+import sys
+
+import click
+
+from airflow_breeze.commands.common_options import argument_doc_packages
+from airflow_breeze.utils.click_utils import BreezeGroup
+from airflow_breeze.utils.console import get_console
+from airflow_breeze.utils.custom_param_types import BetterChoice
+from airflow_breeze.utils.gh_workflow_utils import trigger_workflow_and_monitor
+from airflow_breeze.utils.run_utils import run_command
+
+WORKFLOW_NAME_MAPS = {
+ "publish-docs": "publish-docs-to-s3.yml",
+ "airflow-refresh-site": "build.yml",
+ "sync-s3-to-github": "s3-to-github.yml",
+}
+
+APACHE_AIRFLOW_REPO = "apache/airflow"
+APACHE_AIRFLOW_SITE_REPO = "apache/airflow-site"
+APACHE_AIRFLOW_SITE_ARCHIVE_REPO = "apache/airflow-site-archive"
+
+
[email protected](cls=BreezeGroup, name="workflow-run", help="Tools to manage
Airflow repository workflows ")
+def workflow_run():
+ pass
+
+
+@workflow_run.command(name="publish-docs", help="Trigger publish docs to S3
workflow")
[email protected](
+ "--ref",
+ help="Git reference tag to checkout to build documentation.",
+ required=True,
+)
[email protected](
+ "--exclude-docs",
+ help="Comma separated list of docs packages to exclude from the publish.",
+ default="no-docs-excluded",
+)
[email protected](
+ "--site-env",
+ help="S3 bucket to which the documentation will be published.",
+ default="auto",
+ type=BetterChoice(["auto", "live", "staging"]),
+)
[email protected](
+ "--skip-write-to-stable-folder",
+ help="Skip writing to stable folder.",
+ is_flag=True,
+)
+@argument_doc_packages
+def workflow_run_publish(
+ ref: str,
+ exclude_docs: str,
+ site_env: str,
+ doc_packages: tuple[str, ...],
+ skip_write_to_stable_folder: bool = False,
+):
+ get_console().print(
+ f"[blue]Validating ref: {ref}[/blue]",
+ )
+
+ tag_result = run_command(
+ ["gh", "api", f"repos/apache/airflow/git/refs/tags/{ref}"],
+ capture_output=True,
+ check=False,
+ )
+
+ stdout = tag_result.stdout.decode("utf-8")
+ tag_respo = json.loads(stdout)
+
+ if not tag_respo.get("ref"):
+ get_console().print(
+ f"[red]Error: Ref {ref} is not exists in repo apache/airflow
.[/red]",
+ )
+ sys.exit(1)
+
+ get_console().print(
+ f"[blue]Triggering workflow {WORKFLOW_NAME_MAPS['publish-docs']}: at
{APACHE_AIRFLOW_REPO}[/blue]",
+ )
+
+ workflow_fields = {
+ "ref": ref,
+ "destination": site_env,
+ "include-docs": " ".join(doc_packages),
+ "exclude-docs": exclude_docs,
+ "skip-write-to-stable-folder": skip_write_to_stable_folder,
+ }
+
+ trigger_workflow_and_monitor(
+ workflow_name=WORKFLOW_NAME_MAPS["publish-docs"],
+ repo=APACHE_AIRFLOW_REPO,
+ branch="main",
+ **workflow_fields,
+ )
+
+ if site_env == "auto":
+ pattern = re.compile(r"^.*[0-9]+\.[0-9]+\.[0-9]+$")
+ if pattern.match(ref):
+ site_env = "live"
+ else:
+ site_env = "staging"
+
+ branch = "main" if site_env == "live" else "staging"
+
+ get_console().print(
+ f"[blue]Refreshing site at {APACHE_AIRFLOW_SITE_REPO}[/blue]",
+ )
+ wf_name = WORKFLOW_NAME_MAPS["airflow-refresh-site"]
+
+ get_console().print(
+ f"[blue]Triggering workflow {wf_name}: at
{APACHE_AIRFLOW_SITE_REPO}[/blue]",
+ )
+
+ trigger_workflow_and_monitor(
+ workflow_name=wf_name,
+ repo=APACHE_AIRFLOW_SITE_REPO,
+ branch=branch,
+ )
+
+ get_console().print(
+ f"[blue]Refreshing completed workflow {wf_name}: at
{APACHE_AIRFLOW_SITE_REPO}[/blue]",
+ )
+
+ workflow_fields = {"source": site_env}
+
+ get_console().print(
+ f"[blue]Syncing S3 docs to GitHub repository at
{APACHE_AIRFLOW_SITE_ARCHIVE_REPO}[/blue]",
+ )
+ trigger_workflow_and_monitor(
+ workflow_name=WORKFLOW_NAME_MAPS["sync-s3-to-github"],
+ repo=APACHE_AIRFLOW_SITE_ARCHIVE_REPO,
+ branch=branch,
+ **workflow_fields,
+ monitor=False,
+ )
diff --git a/dev/breeze/src/airflow_breeze/commands/workflow_commands_config.py
b/dev/breeze/src/airflow_breeze/commands/workflow_commands_config.py
new file mode 100644
index 00000000000..6a5025dcf9b
--- /dev/null
+++ b/dev/breeze/src/airflow_breeze/commands/workflow_commands_config.py
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+WORKFLOW_RUN_COMMANDS: dict[str, str | list[str]] = {
+ "name": "Airflow github actions workflow commands",
+ "commands": ["publish-docs"],
+}
+
+WORKFLOW_RUN_PARAMETERS: dict[str, list[dict[str, str | list[str]]]] = {
+ "breeze workflow-run publish-docs": [
+ {
+ "name": "Trigger publish docs workflow",
+ "options": [
+ "--ref",
+ "--exclude-docs",
+ "--site-env",
+ "--skip-write-to-stable-folder",
+ ],
+ },
+ ],
+}
diff --git a/dev/breeze/src/airflow_breeze/configure_rich_click.py
b/dev/breeze/src/airflow_breeze/configure_rich_click.py
index a7a147a04e5..a5b1df980c8 100644
--- a/dev/breeze/src/airflow_breeze/configure_rich_click.py
+++ b/dev/breeze/src/airflow_breeze/configure_rich_click.py
@@ -17,6 +17,7 @@
from __future__ import annotations
from airflow_breeze.commands.sbom_commands_config import SBOM_COMMANDS,
SBOM_PARAMETERS
+from airflow_breeze.commands.workflow_commands_config import
WORKFLOW_RUN_COMMANDS, WORKFLOW_RUN_PARAMETERS
from airflow_breeze.utils import recording # isort:skip # noqa: F401
@@ -76,6 +77,7 @@ else:
**CI_PARAMETERS,
**RELEASE_MANAGEMENT_PARAMETERS,
**SBOM_PARAMETERS,
+ **WORKFLOW_RUN_PARAMETERS,
}
click.rich_click.COMMAND_GROUPS = {
"breeze": [
@@ -90,7 +92,7 @@ else:
},
{
"name": "Release management commands",
- "commands": ["release-management", "sbom"],
+ "commands": ["release-management", "sbom", "workflow-run"],
},
{
"name": "Other commands",
@@ -114,4 +116,5 @@ else:
],
"breeze sbom": [SBOM_COMMANDS],
"breeze ci": [CI_COMMANDS],
+ "breeze workflow-run": [WORKFLOW_RUN_COMMANDS],
}
diff --git a/dev/breeze/src/airflow_breeze/utils/gh_workflow_utils.py
b/dev/breeze/src/airflow_breeze/utils/gh_workflow_utils.py
new file mode 100644
index 00000000000..30659b363b0
--- /dev/null
+++ b/dev/breeze/src/airflow_breeze/utils/gh_workflow_utils.py
@@ -0,0 +1,184 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import json
+import sys
+import time
+
+from airflow_breeze.utils.console import get_console
+from airflow_breeze.utils.run_utils import run_command
+
+
+def tigger_workflow(workflow_name: str, repo: str, branch: str = "main",
**kwargs):
+ """
+ Trigger a GitHub Actions workflow using the `gh` CLI.
+
+ :param workflow_name: The name of the workflow to trigger.
+ :param repo: Workflow repository example: 'apache/airflow'
+ :param branch: The branch to run the workflow on.
+ :param kwargs: Additional parameters to pass to the workflow.
+ """
+ command = ["gh", "workflow", "run", workflow_name, "--ref", branch,
"--repo", repo]
+
+ # These are the input parameters to workflow
+ for key, value in kwargs.items():
+ # GH cli requires bool inputs to be converted to string format
+ if isinstance(value, bool):
+ value = "true" if value else "false"
+
+ command.extend(["-f", f"{key}={value}"])
+
+ get_console().print(f"[blue]Running command: {' '.join(command)}[/blue]")
+ result = run_command(command, capture_output=True, check=False)
+
+ if result.returncode != 0:
+ get_console().print(f"[red]Error running workflow:
{result.stderr}[/red]")
+ sys.exit(1)
+
+ # Wait for a few seconds to start the workflow run
+ time.sleep(5)
+
+
+def get_workflow_run_id(workflow_name: str, repo: str) -> int:
+ """
+ Get the latest workflow run ID for a given workflow name and repository.
+
+ :param workflow_name: The name of the workflow to check.
+ :param repo: The repository in the format 'owner/repo'.
+ """
+ command = [
+ "gh",
+ "run",
+ "list",
+ "--workflow",
+ workflow_name,
+ "--repo",
+ repo,
+ "--limit",
+ "1",
+ "--json",
+ "databaseId",
+ ]
+
+ result = run_command(command, capture_output=True, check=False)
+ if result.returncode != 0:
+ get_console().print(f"[red]Error fetching workflow run ID:
{result.stderr}[/red]")
+ sys.exit(1)
+
+ runs_data = result.stdout.strip()
+ if not runs_data:
+ get_console().print("[red]No workflow runs found.[/red]")
+ sys.exit(1)
+
+ return json.loads(runs_data)[0]["databaseId"]
+
+
+def get_workflow_run_info(run_id: str, repo: str, fields: str) -> dict:
+ """
+ Get the workflow information for a specific run ID and return the
specified fields.
+
+ :param run_id: The ID of the workflow run to check.
+ :param repo: Workflow repository example: 'apache/airflow'
+ :param fields: Comma-separated fields to retrieve from the workflow run to
fetch. eg: "status,conclusion,name,jobs"
+ """
+ command = ["gh", "run", "view", run_id, "--json", fields, "--repo", repo]
+
+ result = run_command(command, capture_output=True, check=False)
+ if result.returncode != 0:
+ get_console().print(f"[red]Error fetching workflow run status:
{result.stderr}[/red]")
+ sys.exit(1)
+
+ return json.loads(result.stdout.strip())
+
+
+def monitor_workflow_run(run_id: str, repo: str):
+ """
+ Monitor the status of a workflow run until it completes.
+
+ :param run_id: The ID of the workflow run to monitor.
+ :param repo: Workflow repository example: 'apache/airflow'
+ """
+
+ completed_jobs = []
+
+ while True:
+ jobs_data = get_workflow_run_info(run_id, repo, "jobs")
+
+ for job in jobs_data.get("jobs", []):
+ name = job["name"]
+ status = job["status"]
+ conclusion = job["conclusion"]
+
+ if name not in completed_jobs and status != "completed":
+ get_console().print(
+ f"[yellow]- Job: {name} | Status: {status} | Conclusion:
{conclusion}[/yellow]"
+ )
+ continue
+
+ if name not in completed_jobs:
+ get_console().print(
+ f"[green]- Job: {name} | Status: {status} | Conclusion:
{conclusion}[/green]"
+ )
+ completed_jobs.append(name)
+
+ workflow_run_status_conclusion = get_workflow_run_info(run_id, repo,
"status,conclusion,name")
+
+ status = workflow_run_status_conclusion.get("status")
+ conclusion = workflow_run_status_conclusion.get("conclusion")
+ name = workflow_run_status_conclusion.get("name")
+
+ if status == "completed":
+ if conclusion == "success":
+ get_console().print(f"[green]Workflow {name} run {run_id}
completed successfully.[/green]")
+ elif conclusion == "failure":
+ get_console().print(
+ f"[red]Workflow {name} run {run_id} failed, see for more
info: https://github.com/{repo}/actions/runs/{run_id}[/red]"
+ )
+ sys.exit(1)
+ break
+
+ # Check status of jobs every 30 seconds
+ time.sleep(30)
+
+
+def trigger_workflow_and_monitor(
+ workflow_name: str, repo: str, branch: str = "main", monitor=True,
**workflow_fields
+):
+ tigger_workflow(
+ workflow_name=workflow_name,
+ repo=repo,
+ branch=branch,
+ **workflow_fields,
+ )
+
+ workflow_run_id = get_workflow_run_id(
+ workflow_name=workflow_name,
+ repo=repo,
+ )
+
+ get_console().print(
+ f"[blue]Workflow run ID: {workflow_run_id}[/blue]",
+ )
+
+ if not monitor:
+ return
+
+ monitor_workflow_run(
+ run_id=str(workflow_run_id),
+ repo=repo,
+ )