1515 - ' dependabot/**'
1616 workflow_dispatch :
1717
18+ permissions :
19+ # Read repository contents for checkout and dependency resolution only.
20+ contents : read
21+
1822env :
1923 # Please make sure this version is included in the `matrix`, as the
2024 # `matrix` section can't use `env`, so it must be entered manually
4347
4448 steps :
4549 - name : Run nox
46- uses : frequenz-floss/gh-action-nox@v1.1.0
50+ uses : frequenz-floss/gh-action-nox@e1351cf45e05e85afc1c79ab883e06322892d34c # v1.1.0
4751 with :
4852 python-version : ${{ matrix.python }}
4953 nox-session : ${{ matrix.nox-session }}
5963 # We skip this job only if nox was also skipped
6064 if : always() && needs.nox.result != 'skipped'
6165 runs-on : ubuntu-slim
66+ # Drop token permissions: this job only checks matrix status from `needs`.
67+ permissions : {}
6268 env :
6369 DEPS_RESULT : ${{ needs.nox.result }}
6470 steps :
@@ -74,24 +80,24 @@ jobs:
7480
7581 steps :
7682 - name : Setup Git
77- uses : frequenz-floss/gh-action-setup-git@v1.0.0
83+ uses : frequenz-floss/gh-action-setup-git@16952aac3ccc01d27412fe0dea3ea946530dcace # v1.0.0
7884
7985 - name : Fetch sources
80- uses : actions/checkout@v6
86+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
8187 with :
8288 submodules : true
8389
8490 - name : Setup Python
85- uses : frequenz-floss/gh-action-setup-python-with-deps@v1.0.2
91+ uses : frequenz-floss/gh-action-setup-python-with-deps@0d0d77eac3b54799f31f25a1060ef2c6ebdf9299 # v1.0.2
8692 with :
8793 python-version : ${{ env.DEFAULT_PYTHON_VERSION }}
8894 dependencies : build
8995
9096 - name : Build the source and binary distribution
91- run : python -m build
97+ run : python -Im build
9298
9399 - name : Upload distribution files
94- uses : actions/upload-artifact@v7
100+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
95101 with :
96102 name : dist-packages
97103 path : dist/
@@ -113,13 +119,13 @@ jobs:
113119
114120 steps :
115121 - name : Setup Git
116- uses : frequenz-floss/gh-action-setup-git@v1.0.0
122+ uses : frequenz-floss/gh-action-setup-git@16952aac3ccc01d27412fe0dea3ea946530dcace # v1.0.0
117123
118124 - name : Print environment (debug)
119125 run : env
120126
121127 - name : Download package
122- uses : actions/download-artifact@v8
128+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
123129 with :
124130 name : dist-packages
125131 path : dist
@@ -139,13 +145,13 @@ jobs:
139145 > pyproject.toml
140146
141147 - name : Setup Python
142- uses : frequenz-floss/gh-action-setup-python-with-deps@v1.0.2
148+ uses : frequenz-floss/gh-action-setup-python-with-deps@0d0d77eac3b54799f31f25a1060ef2c6ebdf9299 # v1.0.2
143149 with :
144150 python-version : ${{ matrix.python }}
145151 dependencies : dist/*.whl
146152
147153 - name : Print installed packages (debug)
148- run : python -m pip freeze
154+ run : python -Im pip freeze
149155
150156 # This job runs if all the `test-installation` matrix jobs ran and succeeded.
151157 # It is only used to have a single job that we can require in branch
@@ -158,6 +164,8 @@ jobs:
158164 # We skip this job only if test-installation was also skipped
159165 if : always() && needs.test-installation.result != 'skipped'
160166 runs-on : ubuntu-slim
167+ # Drop token permissions: this job only checks matrix status from `needs`.
168+ permissions : {}
161169 env :
162170 DEPS_RESULT : ${{ needs.test-installation.result }}
163171 steps :
@@ -170,15 +178,15 @@ jobs:
170178 runs-on : ubuntu-24.04
171179 steps :
172180 - name : Setup Git
173- uses : frequenz-floss/gh-action-setup-git@v1.0.0
181+ uses : frequenz-floss/gh-action-setup-git@16952aac3ccc01d27412fe0dea3ea946530dcace # v1.0.0
174182
175183 - name : Fetch sources
176- uses : actions/checkout@v6
184+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
177185 with :
178186 submodules : true
179187
180188 - name : Setup Python
181- uses : frequenz-floss/gh-action-setup-python-with-deps@v1.0.2
189+ uses : frequenz-floss/gh-action-setup-python-with-deps@0d0d77eac3b54799f31f25a1060ef2c6ebdf9299 # v1.0.2
182190 with :
183191 python-version : ${{ env.DEFAULT_PYTHON_VERSION }}
184192 dependencies : .[dev-mkdocs]
@@ -187,11 +195,14 @@ jobs:
187195 env :
188196 MIKE_VERSION : gh-${{ github.job }}
189197 run : |
190- mike deploy $MIKE_VERSION
191- mike set-default $MIKE_VERSION
198+ # mike is installed as a console script, not a runnable module.
199+ # Run the installed script under isolated mode to avoid importing from
200+ # the workspace when building docs from checked-out code.
201+ python -I "$(command -v mike)" deploy "$MIKE_VERSION"
202+ python -I "$(command -v mike)" set-default "$MIKE_VERSION"
192203
193204 - name : Upload site
194- uses : actions/upload-artifact@v7
205+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
195206 with :
196207 name : docs-site
197208 path : site/
@@ -203,18 +214,19 @@ jobs:
203214 if : github.event_name == 'push'
204215 runs-on : ubuntu-24.04
205216 permissions :
217+ # Push generated documentation updates to the `gh-pages` branch.
206218 contents : write
207219 steps :
208220 - name : Setup Git
209- uses : frequenz-floss/gh-action-setup-git@v1.0.0
221+ uses : frequenz-floss/gh-action-setup-git@16952aac3ccc01d27412fe0dea3ea946530dcace # v1.0.0
210222
211223 - name : Fetch sources
212- uses : actions/checkout@v6
224+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
213225 with :
214226 submodules : true
215227
216228 - name : Setup Python
217- uses : frequenz-floss/gh-action-setup-python-with-deps@v1.0.2
229+ uses : frequenz-floss/gh-action-setup-python-with-deps@0d0d77eac3b54799f31f25a1060ef2c6ebdf9299 # v1.0.2
218230 with :
219231 python-version : ${{ env.DEFAULT_PYTHON_VERSION }}
220232 dependencies : .[dev-mkdocs]
@@ -227,7 +239,7 @@ jobs:
227239 GIT_REF : ${{ github.ref }}
228240 GIT_SHA : ${{ github.sha }}
229241 run : |
230- python -m frequenz.repo.config.cli.version.mike.info
242+ python -Im frequenz.repo.config.cli.version.mike.info
231243
232244 - name : Fetch the gh-pages branch
233245 if : steps.mike-version.outputs.version
@@ -248,13 +260,23 @@ jobs:
248260 GIT_REF : ${{ github.ref }}
249261 GIT_SHA : ${{ github.sha }}
250262 run : |
251- mike deploy --update-aliases --title "$TITLE" "$VERSION" $ALIASES
263+ # Collect aliases into an array to avoid accidental (or malicious)
264+ # shell injection when passing them to mike.
265+ aliases=()
266+ if test -n "$ALIASES"; then
267+ read -r -a aliases <<<"$ALIASES"
268+ fi
269+ # mike is installed as a console script, not a runnable module.
270+ # Run the installed script under isolated mode to avoid importing from
271+ # the workspace when building docs from checked-out code.
272+ python -I "$(command -v mike)" \
273+ deploy --update-aliases --title "$TITLE" "$VERSION" "${aliases[@]}"
252274
253275 - name : Sort site versions
254276 if : steps.mike-version.outputs.version
255277 run : |
256278 git checkout gh-pages
257- python -m frequenz.repo.config.cli.version.mike.sort versions.json
279+ python -Im frequenz.repo.config.cli.version.mike.sort versions.json
258280 git commit -a -m "Sort versions.json"
259281
260282 - name : Publish site
@@ -268,14 +290,12 @@ jobs:
268290 # Create a release only on tags creation
269291 if : github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
270292 permissions :
271- # We need write permissions on contents to create GitHub releases and on
272- # discussions to create the release announcement in the discussion forums
293+ # Create GitHub releases and upload distribution artifacts.
273294 contents : write
274- discussions : write
275295 runs-on : ubuntu-slim
276296 steps :
277297 - name : Download distribution files
278- uses : actions/download-artifact@v8
298+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
279299 with :
280300 name : dist-packages
281301 path : dist
@@ -297,14 +317,14 @@ jobs:
297317 - name : Create GitHub release
298318 run : |
299319 set -ux
300- extra_opts=
301- if echo "$REF_NAME" | grep -- -; then extra_opts=" --prerelease" ; fi
320+ extra_opts=()
321+ if echo "$REF_NAME" | grep -- -; then extra_opts+=( --prerelease) ; fi
302322 gh release create \
303323 -R "$REPOSITORY" \
304324 --notes-file RELEASE_NOTES.md \
305325 --generate-notes \
306- $ extra_opts \
307- $REF_NAME \
326+ "${ extra_opts[@]}" \
327+ " $REF_NAME" \
308328 dist/*
309329 env :
310330 REF_NAME : ${{ github.ref_name }}
@@ -321,10 +341,10 @@ jobs:
321341 id-token : write
322342 steps :
323343 - name : Download distribution files
324- uses : actions/download-artifact@v8
344+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
325345 with :
326346 name : dist-packages
327347 path : dist
328348
329349 - name : Publish the Python distribution to PyPI
330- uses : pypa/gh-action-pypi-publish@release/v1
350+ uses : pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
0 commit comments