This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch v3-2-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-2-test by this push:
new f6ee186e1e2 Release docs: port airflowctl fixes and guidance to other
components (#65576) (#65582)
f6ee186e1e2 is described below
commit f6ee186e1e2701459b3bbe579bce4d2471bc266d
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sun Apr 26 14:06:25 2026 +0200
Release docs: port airflowctl fixes and guidance to other components
(#65576) (#65582)
Apply fixes and additions that landed in the airflow-ctl release README to
the airflow, providers, python-client, and helm-chart release READMEs:
- Fix `rm -rf /tmp/apache/...-src` typo where the cleanup path did not match
the subsequent `mkdir -p /tmp/apache-...-src` (providers, python-client).
- Add defensive `cd "${AIRFLOW_REPO_ROOT}"` before `git fetch apache --tags`
in the reproducible-build sections (providers, python-client).
- Add "Collect ambiguities during the release" section encouraging release
managers to keep a scratch file outside the repo for follow-up doc PRs
(all four docs).
- Add "Verify your GPG signing key is ready" preflight block so signing
failures surface before artifact build (all four docs).
- Add PyPI token single-use/deletion guidance before every upload step —
create a short-lived token, run the upload, delete it immediately
(airflow, providers, python-client).
- Rename "Add tags in git" to "Add the final release tag in git" in the
post-vote section where it was ambiguous with the RC-tag step (providers).
Co-authored-by: Jarek Potiuk <[email protected]>
---
dev/README_RELEASE_AIRFLOW.md | 95 ++++++++++++++++++++++++++++++++
dev/README_RELEASE_HELM_CHART.md | 49 +++++++++++++++++
dev/README_RELEASE_PROVIDERS.md | 106 ++++++++++++++++++++++++++++++++++--
dev/README_RELEASE_PYTHON_CLIENT.md | 102 +++++++++++++++++++++++++++++++++-
4 files changed, 344 insertions(+), 8 deletions(-)
diff --git a/dev/README_RELEASE_AIRFLOW.md b/dev/README_RELEASE_AIRFLOW.md
index 28a032e5770..80beae13d76 100644
--- a/dev/README_RELEASE_AIRFLOW.md
+++ b/dev/README_RELEASE_AIRFLOW.md
@@ -20,6 +20,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of contents**
+- [Collect ambiguities during the release (for a follow-up doc
PR)](#collect-ambiguities-during-the-release-for-a-follow-up-doc-pr)
- [Perform review of security issues that are marked for the
release](#perform-review-of-security-issues-that-are-marked-for-the-release)
- [Selecting what to put into the
release](#selecting-what-to-put-into-the-release)
- [i18n workflow](#i18n-workflow)
@@ -68,6 +69,21 @@
You can find the prerequisites to release Apache Airflow in
[README.md](README.md).
+# Collect ambiguities during the release (for a follow-up doc PR)
+
+These instructions are imperfect. Every release uncovers at least one command
+that has drifted, one step that is under-documented, or one automation that
+silently did the wrong thing. As you run through this document, jot down any
+such observations in a scratch file kept **outside** the repo (anywhere that
+is not tracked by git — a note in your home directory, a scratchpad, a
+gist). Once the release has landed, turn those notes into a follow-up PR
+against this document.
+
+Keeping the scratch file out of the repo avoids accidentally committing
+release-manager notes along with the release-prep PR, and makes it obvious
+that the notes are input to the next doc PR rather than something to keep
+around long-term.
+
# Perform review of security issues that are marked for the release
We are keeping track of security issues in the [Security
Issues](https://github.com/airflow-s/airflow-s/issues)
@@ -377,6 +393,39 @@ export AIRFLOW_REPO_ROOT=$(pwd)
uv tool install -e ./dev/breeze
```
+- Verify your GPG signing key is ready.
+
+ Before you spend 10+ minutes building artifacts only to discover that signing
+ fails, run these checks once:
+
+ ```shell script
+ # 1. The apache.org key has a secret signing subkey available locally.
+ gpg --list-secret-keys apache.org
+
+ # 2. Signing actually works (exits 0, writes a .asc, verifies cleanly).
+ echo test > /tmp/sign-check && \
+ gpg --yes --armor --local-user apache.org \
+ --output /tmp/sign-check.asc --detach-sig /tmp/sign-check && \
+ gpg --verify /tmp/sign-check.asc /tmp/sign-check && \
+ rm -f /tmp/sign-check /tmp/sign-check.asc && \
+ echo "GPG signing OK"
+
+ # 3. The fingerprint of your signing (sub)key appears in the Airflow KEYS
file.
+ # Without this, PMC verifiers cannot validate the release.
+ FINGERPRINT=$(gpg --list-keys --with-colons apache.org | awk -F: '/^fpr:/
{print $10; exit}')
+ curl -fsS https://dist.apache.org/repos/dist/release/airflow/KEYS | \
+ grep -q "${FINGERPRINT}" && echo "Key ${FINGERPRINT} is in KEYS" || \
+ echo "MISSING: add your key to KEYS before releasing"
+ ```
+
+ If any of these fail, fix them before the build step. For first-time release
+ managers, adding your key to the `KEYS` file is a separate PR against
+ `https://dist.apache.org/repos/dist/release/airflow/` (SVN).
+
+ `sign.sh` defaults to `SIGN_WITH=apache.org`. If your `apache.org` uid
resolves
+ to multiple keys (rare), set `SIGN_WITH` explicitly to the fingerprint of the
+ key you want to use.
+
- For major/minor version release, run the following commands to create the
'test' and 'stable' branches.
```shell script
@@ -478,6 +527,30 @@ uv tool install -e ./dev/breeze
export GITHUB_TOKEN="my_token"
```
+- Configure a short-lived PyPI token for this upload only. **Until Trusted
+ Publishing is deployed for apache-airflow on PyPI**, the recommended
+ practice is:
+
+ 1. Log in to https://pypi.org and create an API token right before the
+ upload step. **Scope caveat:** you would ideally create a
+ project-scoped token for `apache-airflow` alone, but PyPI only
+ allows project-scoped tokens for projects you already own/maintain on
+ that account. Most Airflow release managers do not have per-project
+ owner rights on `apache-airflow`, so in practice you will need to
+ create an account-wide ("all projects") token. That is acceptable
+ **only if** you treat it as single-use and delete it immediately
+ after the upload (step 4 below). Never keep an all-projects token on
+ disk longer than the upload itself.
+ 2. Put it in `~/.pypirc` (or export as `TWINE_USERNAME=__token__`
+ `TWINE_PASSWORD=pypi-...`).
+ 3. Run the `start-rc-process` command (below) — it uploads to PyPI under
+ the hood.
+ 4. **Immediately delete the token** from the PyPI web UI after the upload
+ completes. Do not keep long-lived release-manager tokens on disk.
+
+ This is a defence-in-depth practice: the RM machine becomes a one-time
+ release vehicle, not a persistent point of compromise.
+
- Start the release candidate process by running the below command (If you
have not generated a key yet, generate it by following instructions on
http://www.apache.org/dev/openpgp.html#key-gen-generate-key):
@@ -1238,6 +1311,28 @@ https://dist.apache.org/repos/dist/release/airflow/
The best way of doing this is to svn cp between the two repos (this avoids
having to upload the binaries again, and gives a clearer history in the svn
commit logs):
+Before running `start-release`, configure a short-lived PyPI token for this
+upload only. **Until Trusted Publishing is deployed for apache-airflow on
+PyPI**, the recommended practice is:
+
+1. Log in to https://pypi.org and create an API token right before the
+ upload step. **Scope caveat:** you would ideally create a project-scoped
+ token for `apache-airflow` alone, but PyPI only allows project-scoped
+ tokens for projects you already own/maintain on that account. Most
+ Airflow release managers do not have per-project owner rights on
+ `apache-airflow`, so in practice you will need to create an account-wide
+ ("all projects") token. That is acceptable **only if** you treat it as
+ single-use and delete it immediately after the upload (step 4 below).
+ Never keep an all-projects token on disk longer than the upload itself.
+2. Put it in `~/.pypirc` (or export as `TWINE_USERNAME=__token__`
+ `TWINE_PASSWORD=pypi-...`).
+3. Run the `start-release` command below — it uploads to PyPI under the hood.
+4. **Immediately delete the token** from the PyPI web UI after the upload
+ completes. Do not keep long-lived release-manager tokens on disk.
+
+This is a defence-in-depth practice: the RM machine becomes a one-time
+release vehicle, not a persistent point of compromise.
+
```shell script
export VERSION=3.1.3
export TASK_SDK_VERSION=1.1.3
diff --git a/dev/README_RELEASE_HELM_CHART.md b/dev/README_RELEASE_HELM_CHART.md
index 1c06a0be344..1c6dcaffc2a 100644
--- a/dev/README_RELEASE_HELM_CHART.md
+++ b/dev/README_RELEASE_HELM_CHART.md
@@ -20,6 +20,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of contents**
+- [Collect ambiguities during the release (for a follow-up doc
PR)](#collect-ambiguities-during-the-release-for-a-follow-up-doc-pr)
- [Perform review of security issues that are marked for the
release](#perform-review-of-security-issues-that-are-marked-for-the-release)
- [Prepare the Apache Airflow Helm Chart Release
Candidate](#prepare-the-apache-airflow-helm-chart-release-candidate)
- [Pre-requisites](#pre-requisites)
@@ -65,6 +66,21 @@
You can find the prerequisites to release Apache Airflow in
[README.md](README.md). This document
details the steps for releasing Helm Chart.
+# Collect ambiguities during the release (for a follow-up doc PR)
+
+These instructions are imperfect. Every release uncovers at least one command
+that has drifted, one step that is under-documented, or one automation that
+silently did the wrong thing. As you run through this document, jot down any
+such observations in a scratch file kept **outside** the repo (anywhere that
+is not tracked by git — a note in your home directory, a scratchpad, a
+gist). Once the release has landed, turn those notes into a follow-up PR
+against this document.
+
+Keeping the scratch file out of the repo avoids accidentally committing
+release-manager notes along with the release-prep PR, and makes it obvious
+that the notes are input to the next doc PR rather than something to keep
+around long-term.
+
# Perform review of security issues that are marked for the release
We are keeping track of security issues in the [Security
Issues](https://github.com/airflow-s/airflow-s/issues)
@@ -228,6 +244,39 @@ git clean -fxd
rm -rf dist/*
```
+- Verify your GPG signing key is ready.
+
+ Before you spend 10+ minutes building artifacts only to discover that signing
+ fails, run these checks once:
+
+ ```shell
+ # 1. The apache.org key has a secret signing subkey available locally.
+ gpg --list-secret-keys apache.org
+
+ # 2. Signing actually works (exits 0, writes a .asc, verifies cleanly).
+ echo test > /tmp/sign-check && \
+ gpg --yes --armor --local-user apache.org \
+ --output /tmp/sign-check.asc --detach-sig /tmp/sign-check && \
+ gpg --verify /tmp/sign-check.asc /tmp/sign-check && \
+ rm -f /tmp/sign-check /tmp/sign-check.asc && \
+ echo "GPG signing OK"
+
+ # 3. The fingerprint of your signing (sub)key appears in the Airflow KEYS
file.
+ # Without this, PMC verifiers cannot validate the release.
+ FINGERPRINT=$(gpg --list-keys --with-colons apache.org | awk -F: '/^fpr:/
{print $10; exit}')
+ curl -fsS https://dist.apache.org/repos/dist/release/airflow/KEYS | \
+ grep -q "${FINGERPRINT}" && echo "Key ${FINGERPRINT} is in KEYS" || \
+ echo "MISSING: add your key to KEYS before releasing"
+ ```
+
+ If any of these fail, fix them before the build step. For first-time release
+ managers, adding your key to the `KEYS` file is a separate PR against
+ `https://dist.apache.org/repos/dist/release/airflow/` (SVN).
+
+ `sign.sh` defaults to `SIGN_WITH=apache.org`. If your `apache.org` uid
resolves
+ to multiple keys (rare), set `SIGN_WITH` explicitly to the fingerprint of the
+ key you want to use.
+
- Generate the source tarball:
```shell
diff --git a/dev/README_RELEASE_PROVIDERS.md b/dev/README_RELEASE_PROVIDERS.md
index 74d806416b0..4cc353e3f4e 100644
--- a/dev/README_RELEASE_PROVIDERS.md
+++ b/dev/README_RELEASE_PROVIDERS.md
@@ -23,6 +23,7 @@
- [Intro](#intro)
- [What the provider distributions are](#what-the-provider-distributions-are)
- [Decide when to release](#decide-when-to-release)
+- [Collect ambiguities during the release (for a follow-up doc
PR)](#collect-ambiguities-during-the-release-for-a-follow-up-doc-pr)
- [Special procedures (done very
infrequently)](#special-procedures-done-very-infrequently)
- [Bump min Airflow version for
providers](#bump-min-airflow-version-for-providers)
- [Move provider into remove state](#move-provider-into-remove-state)
@@ -48,7 +49,7 @@
- [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)
- - [Add tags in git](#add-tags-in-git)
+ - [Add the final release tag in git](#add-the-final-release-tag-in-git)
- [Publish documentation](#publish-documentation)
- [Update providers metadata](#update-providers-metadata)
- [Notify developers of release](#notify-developers-of-release)
@@ -86,6 +87,21 @@ a given provider needs to be released due to new features or
due to bug fixes.
package separately, but due to voting and release overhead we try to group
releases of Provider
distributions together.
+# Collect ambiguities during the release (for a follow-up doc PR)
+
+These instructions are imperfect. Every release uncovers at least one command
+that has drifted, one step that is under-documented, or one automation that
+silently did the wrong thing. As you run through this document, jot down any
+such observations in a scratch file kept **outside** the repo (anywhere that
+is not tracked by git — a note in your home directory, a scratchpad, a
+gist). Once the release has landed, turn those notes into a follow-up PR
+against this document.
+
+Keeping the scratch file out of the repo avoids accidentally committing
+release-manager notes along with the release-prep PR, and makes it obvious
+that the notes are input to the next doc PR rather than something to keep
+around long-term.
+
# Special procedures (done very infrequently)
> [!NOTE]
@@ -340,6 +356,39 @@ Linux (Debian/Ubuntu):
sudo apt-get install libassuan-dev gnupg
```
+### Verify your GPG signing key is ready
+
+Before you spend 10+ minutes building artifacts only to discover that signing
+fails, run these checks once:
+
+```shell script
+# 1. The apache.org key has a secret signing subkey available locally.
+gpg --list-secret-keys apache.org
+
+# 2. Signing actually works (exits 0, writes a .asc, verifies cleanly).
+echo test > /tmp/sign-check && \
+ gpg --yes --armor --local-user apache.org \
+ --output /tmp/sign-check.asc --detach-sig /tmp/sign-check && \
+ gpg --verify /tmp/sign-check.asc /tmp/sign-check && \
+ rm -f /tmp/sign-check /tmp/sign-check.asc && \
+ echo "GPG signing OK"
+
+# 3. The fingerprint of your signing (sub)key appears in the Airflow KEYS file.
+# Without this, PMC verifiers cannot validate the release.
+FINGERPRINT=$(gpg --list-keys --with-colons apache.org | awk -F: '/^fpr:/
{print $10; exit}')
+curl -fsS https://dist.apache.org/repos/dist/release/airflow/KEYS | \
+ grep -q "${FINGERPRINT}" && echo "Key ${FINGERPRINT} is in KEYS" || \
+ echo "MISSING: add your key to KEYS before releasing"
+```
+
+If any of these fail, fix them before the build step. For first-time release
+managers, adding your key to the `KEYS` file is a separate PR against
+`https://dist.apache.org/repos/dist/release/airflow/` (SVN).
+
+`sign.sh` defaults to `SIGN_WITH=apache.org`. If your `apache.org` uid resolves
+to multiple keys (rare), set `SIGN_WITH` explicitly to the fingerprint of the
+key you want to use.
+
## Build and sign the source and convenience packages
* Cleanup dist folder:
@@ -482,7 +531,30 @@ increased until the tag is not found.
twine check ${AIRFLOW_REPO_ROOT}/dist/*
```
-* Upload the package to PyPi:
+* Configure a short-lived PyPI token for this upload only. **Until Trusted
+ Publishing is deployed for the Airflow provider distributions on PyPI**,
+ the recommended practice is:
+
+ 1. Log in to https://pypi.org and create an API token right before the
+ upload step. **Scope caveat:** you would ideally create a
+ project-scoped token, but PyPI only allows project-scoped tokens for
+ projects you already own/maintain on that account. Most Airflow
+ release managers do not have per-project owner rights on every
+ provider being released, so in practice you will need to create an
+ account-wide ("all projects") token. That is acceptable **only if**
+ you treat it as single-use and delete it immediately after the upload
+ (step 4 below). Never keep an all-projects token on disk longer than
+ the upload itself.
+ 2. Put it in `~/.pypirc` (or export as `TWINE_USERNAME=__token__`
+ `TWINE_PASSWORD=pypi-...`).
+ 3. Run the upload (below).
+ 4. **Immediately delete the token** from the PyPI web UI after the upload
+ completes. Do not keep long-lived release-manager tokens on disk.
+
+ This is a defence-in-depth practice: the RM machine becomes a one-time
+ release vehicle, not a persistent point of compromise.
+
+* Upload the package to PyPI:
```shell script
twine upload -r pypi ${AIRFLOW_REPO_ROOT}/dist/*
@@ -776,6 +848,7 @@ cd "$AIRFLOW_REPO_ROOT"
2) Check out the ``providers/YYYY-MM-DD`` tag:
```shell
+cd "$AIRFLOW_REPO_ROOT"
git fetch apache --tags
git checkout providers/${RELEASE_DATE}
```
@@ -869,7 +942,7 @@ tar -xzf /tmp/apache-rat-0.17-bin.tar.gz -C /tmp
Unpack the release source archive (the `<package + version>-source.tar.gz`
file) to a folder
```shell script
-rm -rf /tmp/apache/airflow-providers-src && mkdir -p
/tmp/apache-airflow-providers-src && tar -xzf
${PATH_TO_AIRFLOW_SVN}/providers/${RELEASE_DATE}/apache_airflow_providers-*-source.tar.gz
--strip-components 1 -C /tmp/apache-airflow-providers-src
+rm -rf /tmp/apache-airflow-providers-src && mkdir -p
/tmp/apache-airflow-providers-src && tar -xzf
${PATH_TO_AIRFLOW_SVN}/providers/${RELEASE_DATE}/apache_airflow_providers-*-source.tar.gz
--strip-components 1 -C /tmp/apache-airflow-providers-src
```
Run the check:
@@ -1275,7 +1348,30 @@ rm
dist/apache_airflow_providers-${RELEASE_DATE}-source.tar.gz
twine check ${AIRFLOW_REPO_ROOT}/dist/*.whl ${AIRFLOW_REPO_ROOT}/dist/*.tar.gz
```
-* Upload the package to PyPi:
+* Configure a short-lived PyPI token for this upload only. **Until Trusted
+ Publishing is deployed for the Airflow provider distributions on PyPI**,
+ the recommended practice is:
+
+ 1. Log in to https://pypi.org and create an API token right before the
+ upload step. **Scope caveat:** you would ideally create a
+ project-scoped token, but PyPI only allows project-scoped tokens for
+ projects you already own/maintain on that account. Most Airflow
+ release managers do not have per-project owner rights on every
+ provider being released, so in practice you will need to create an
+ account-wide ("all projects") token. That is acceptable **only if**
+ you treat it as single-use and delete it immediately after the upload
+ (step 4 below). Never keep an all-projects token on disk longer than
+ the upload itself.
+ 2. Put it in `~/.pypirc` (or export as `TWINE_USERNAME=__token__`
+ `TWINE_PASSWORD=pypi-...`).
+ 3. Run the upload (below).
+ 4. **Immediately delete the token** from the PyPI web UI after the upload
+ completes. Do not keep long-lived release-manager tokens on disk.
+
+ This is a defence-in-depth practice: the RM machine becomes a one-time
+ release vehicle, not a persistent point of compromise.
+
+* Upload the package to PyPI:
```shell script
twine upload -r pypi ${AIRFLOW_REPO_ROOT}/dist/*.whl
${AIRFLOW_REPO_ROOT}/dist/*.tar.gz
@@ -1288,7 +1384,7 @@ 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.
-## Add tags in git
+## Add the final release tag in git
Assume that your remote for apache repository is called `apache` you should now
set tags for the providers in the repository.
diff --git a/dev/README_RELEASE_PYTHON_CLIENT.md
b/dev/README_RELEASE_PYTHON_CLIENT.md
index 68d6e57d044..516b7feda13 100644
--- a/dev/README_RELEASE_PYTHON_CLIENT.md
+++ b/dev/README_RELEASE_PYTHON_CLIENT.md
@@ -21,6 +21,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with
[DocToc](https://github.com/thlorenz/doctoc)*
+- [Collect ambiguities during the release (for a follow-up doc
PR)](#collect-ambiguities-during-the-release-for-a-follow-up-doc-pr)
- [Perform review of security issues that are marked for the
release](#perform-review-of-security-issues-that-are-marked-for-the-release)
- [Release package](#release-package)
- [Prepare PyPI convenience "RC"
packages](#prepare-pypi-convenience-rc-packages)
@@ -38,6 +39,21 @@
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
+# Collect ambiguities during the release (for a follow-up doc PR)
+
+These instructions are imperfect. Every release uncovers at least one command
+that has drifted, one step that is under-documented, or one automation that
+silently did the wrong thing. As you run through this document, jot down any
+such observations in a scratch file kept **outside** the repo (anywhere that
+is not tracked by git — a note in your home directory, a scratchpad, a
+gist). Once the release has landed, turn those notes into a follow-up PR
+against this document.
+
+Keeping the scratch file out of the repo avoids accidentally committing
+release-manager notes along with the release-prep PR, and makes it obvious
+that the notes are input to the next doc PR rather than something to keep
+around long-term.
+
# Perform review of security issues that are marked for the release
We are keeping track of security issues in the [Security
Issues](https://github.com/airflow-s/airflow-s/issues)
@@ -195,6 +211,39 @@ breeze release-management prepare-tarball --tarball-type
apache_airflow_python_c
- Generate signatures and checksum files for the packages (if you have not
generated a key yet, generate
it by following instructions on
http://www.apache.org/dev/openpgp.html#key-gen-generate-key)
+- Verify your GPG signing key is ready.
+
+ Before you spend 10+ minutes building artifacts only to discover that signing
+ fails, run these checks once:
+
+ ```shell script
+ # 1. The apache.org key has a secret signing subkey available locally.
+ gpg --list-secret-keys apache.org
+
+ # 2. Signing actually works (exits 0, writes a .asc, verifies cleanly).
+ echo test > /tmp/sign-check && \
+ gpg --yes --armor --local-user apache.org \
+ --output /tmp/sign-check.asc --detach-sig /tmp/sign-check && \
+ gpg --verify /tmp/sign-check.asc /tmp/sign-check && \
+ rm -f /tmp/sign-check /tmp/sign-check.asc && \
+ echo "GPG signing OK"
+
+ # 3. The fingerprint of your signing (sub)key appears in the Airflow KEYS
file.
+ # Without this, PMC verifiers cannot validate the release.
+ FINGERPRINT=$(gpg --list-keys --with-colons apache.org | awk -F: '/^fpr:/
{print $10; exit}')
+ curl -fsS https://dist.apache.org/repos/dist/release/airflow/KEYS | \
+ grep -q "${FINGERPRINT}" && echo "Key ${FINGERPRINT} is in KEYS" || \
+ echo "MISSING: add your key to KEYS before releasing"
+ ```
+
+ If any of these fail, fix them before the build step. For first-time release
+ managers, adding your key to the `KEYS` file is a separate PR against
+ `https://dist.apache.org/repos/dist/release/airflow/` (SVN).
+
+ `sign.sh` defaults to `SIGN_WITH=apache.org`. If your `apache.org` uid
resolves
+ to multiple keys (rare), set `SIGN_WITH` explicitly to the fingerprint of the
+ key you want to use.
+
```shell script
cd ${AIRFLOW_REPO_ROOT}
pushd dist
@@ -251,7 +300,30 @@ breeze release-management prepare-python-client
--distribution-format both --ver
twine check dist/*
```
-- Upload the package to PyPi's production environment:
+- Configure a short-lived PyPI token for this upload only. **Until Trusted
+ Publishing is deployed for apache-airflow-client on PyPI**, the
+ recommended practice is:
+
+ 1. Log in to https://pypi.org and create an API token right before the
+ upload step. **Scope caveat:** you would ideally create a
+ project-scoped token for `apache-airflow-client` alone, but PyPI only
+ allows project-scoped tokens for projects you already own/maintain on
+ that account. Most Airflow release managers do not have per-project
+ owner rights on `apache-airflow-client`, so in practice you will need
+ to create an account-wide ("all projects") token. That is acceptable
+ **only if** you treat it as single-use and delete it immediately
+ after the upload (step 4 below). Never keep an all-projects token on
+ disk longer than the upload itself.
+ 2. Put it in `~/.pypirc` (or export as `TWINE_USERNAME=__token__`
+ `TWINE_PASSWORD=pypi-...`).
+ 3. Run the upload (below).
+ 4. **Immediately delete the token** from the PyPI web UI after the upload
+ completes. Do not keep long-lived release-manager tokens on disk.
+
+ This is a defence-in-depth practice: the RM machine becomes a one-time
+ release vehicle, not a persistent point of compromise.
+
+- Upload the package to PyPI's production environment:
```shell script
twine upload -r pypi dist/*
@@ -391,6 +463,7 @@ cd "${AIRFLOW_REPO_ROOT}"
3) Check out the ``python-client`` tag (assume apache is the remote name of
the repository):
```shell
+cd "${AIRFLOW_REPO_ROOT}"
git fetch apache --tags
git checkout python-client/${VERSION_RC}
```
@@ -471,7 +544,7 @@ tar -xzf /tmp/apache-rat-0.17-bin.tar.gz -C /tmp
Unpack the release source archive (the `<package + version>-source.tar.gz`
file) to a folder
```shell script
-rm -rf /tmp/apache/airflow-python-client-src && mkdir -p
/tmp/apache-airflow-python-client-src && tar -xzf
${PATH_TO_AIRFLOW_SVN}/clients/python/${VERSION_RC}/apache_airflow_python_client-*-source.tar.gz
--strip-components 1 -C /tmp/apache-airflow-python-client-src
+rm -rf /tmp/apache-airflow-python-client-src && mkdir -p
/tmp/apache-airflow-python-client-src && tar -xzf
${PATH_TO_AIRFLOW_SVN}/clients/python/${VERSION_RC}/apache_airflow_python_client-*-source.tar.gz
--strip-components 1 -C /tmp/apache-airflow-python-client-src
```
Run the check:
@@ -745,7 +818,30 @@ cd ${VERSION}
twine check *${VERSION}.tar.gz *.whl
```
-- Upload the package to PyPi's production environment:
+- Configure a short-lived PyPI token for this upload only. **Until Trusted
+ Publishing is deployed for apache-airflow-client on PyPI**, the
+ recommended practice is:
+
+ 1. Log in to https://pypi.org and create an API token right before the
+ upload step. **Scope caveat:** you would ideally create a
+ project-scoped token for `apache-airflow-client` alone, but PyPI only
+ allows project-scoped tokens for projects you already own/maintain on
+ that account. Most Airflow release managers do not have per-project
+ owner rights on `apache-airflow-client`, so in practice you will need
+ to create an account-wide ("all projects") token. That is acceptable
+ **only if** you treat it as single-use and delete it immediately
+ after the upload (step 4 below). Never keep an all-projects token on
+ disk longer than the upload itself.
+ 2. Put it in `~/.pypirc` (or export as `TWINE_USERNAME=__token__`
+ `TWINE_PASSWORD=pypi-...`).
+ 3. Run the upload (below).
+ 4. **Immediately delete the token** from the PyPI web UI after the upload
+ completes. Do not keep long-lived release-manager tokens on disk.
+
+ This is a defence-in-depth practice: the RM machine becomes a one-time
+ release vehicle, not a persistent point of compromise.
+
+- Upload the package to PyPI's production environment:
```shell script
twine upload -r pypi *${VERSION}.tar.gz *.whl