1111
1212 workflow_dispatch :
1313
14- permissions :
15- contents : read
16- id-token : write
17-
1814jobs :
1915 build_sdist :
2016 name : Build source distribution
@@ -38,50 +34,105 @@ jobs:
3834 upload_test_pypi :
3935 needs : [build_sdist]
4036 runs-on : ubuntu-latest
37+ permissions :
38+ id-token : write
4139 steps :
4240 - name : Install Python (if missing)
43- run : apt-get update && apt-get install -y python3 python3-pip
41+ run : |
42+ sudo apt-get update
43+ sudo apt-get install -y python3 python3-pip
4444
4545 - name : Update python dependencies
46- run : python3 -m pip install -U packaging --break-system-packages
46+ run : |
47+ python3 -m venv venv
48+ source venv/bin/activate
49+ pip install -U packaging
4750
4851 - uses : actions/download-artifact@v4
4952 with :
5053 name : artifact
5154 path : dist
5255
56+ - name : mint API token
57+ id : mint-token
58+ run : |
59+ # retrieve the ambient OIDC token
60+ resp=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
61+ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=testpypi")
62+ oidc_token=$(jq -r '.value' <<< "${resp}")
63+
64+ # exchange the OIDC token for an API token
65+ resp=$(curl -X POST https://pypi.org/_/oidc/mint-token -d "{\"token\": \"${oidc_token}\"}")
66+ api_token=$(jq -r '.token' <<< "${resp}")
67+
68+ # mask the newly minted API token, so that we don't accidentally leak it
69+ echo "::add-mask::${api_token}"
70+
71+ # see the next step in the workflow for an example of using this step output
72+ echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}"
73+
5374 - name : Publish package to TestPyPI
75+ env :
76+ PATH : ${{ github.workspace }}/venv/bin:$PATH
5477 uses : pypa/gh-action-pypi-publish@release/v1
5578 with :
79+ password : ${{ steps.mint-token.outputs.api-token }}
5680 repository-url : https://test.pypi.org/legacy/
5781
5882 upload_pypi :
5983 needs : [build_sdist]
6084 runs-on : ubuntu-latest
85+ permissions :
86+ id-token : write
6187 if : startsWith(github.ref, 'refs/tags/v') && github.repository == 'linux-nvme/libnvme'
6288 steps :
6389 - name : Install Python (if missing)
64- run : apt-get update && apt-get install -y python3 python3-pip
90+ run : |
91+ sudo apt-get update
92+ sudo apt-get install -y python3 python3-pip
6593
6694 - name : Update python dependencies
67- run : python3 -m pip install -U packaging --break-system-packages
95+ run : |
96+ python3 -m venv venv
97+ source venv/bin/activate
98+ pip install -U packaging
6899
69100 - name : Check if it is a release tag
70101 id : check-tag
71102 run : |
72103 if [[ ${{ github.event.ref }} =~ ^refs/tags/v([0-9]+\.[0-9]+)(\.[0-9]+)?(-rc[0-9]+)?$ ]]; then
73104 echo ::set-output name=match::true
74105 fi
106+
75107 - name : Download artifiact
76108 uses : actions/download-artifact@v4
77109 if : steps.check-tag.outputs.match == 'true'
78110 with :
79111 name : artifact
80112 path : dist
113+
114+ - name : mint API token
115+ id : mint-token
116+ run : |
117+ # retrieve the ambient OIDC token
118+ resp=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
119+ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=pypi")
120+ oidc_token=$(jq -r '.value' <<< "${resp}")
121+
122+ # exchange the OIDC token for an API token
123+ resp=$(curl -X POST https://pypi.org/_/oidc/mint-token -d "{\"token\": \"${oidc_token}\"}")
124+ api_token=$(jq -r '.token' <<< "${resp}")
125+
126+ # mask the newly minted API token, so that we don't accidentally leak it
127+ echo "::add-mask::${api_token}"
128+
129+ # see the next step in the workflow for an example of using this step output
130+ echo "api-token=${api_token}" >> "${GITHUB_OUTPUT}"
131+
81132 - name : Publish package to PyPI
133+ env :
134+ PATH : ${{ github.workspace }}/venv/bin:$PATH
82135 uses : pypa/gh-action-pypi-publish@release/v1
83136 if : steps.check-tag.outputs.match == 'true'
84137 with :
85- user : __token__
86- password : ${{ secrets.PYPI_API_TOKEN }}
87- verify-metadata : false
138+ password : ${{ steps.mint-token.outputs.api-token }}
0 commit comments