Repository navigation
130 lines (115 loc) · 4.87 KB
/
Copy pathpython-release.yml
File metadata and controls
130 lines (115 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
name: Release
# The release job in test.yml creates the GitHub release (and tag) with the
# release app token once the changie release PR is merged, which triggers this
# workflow. It is the PyPI trusted publisher, so keep its name and environment.
on:
release:
types: [created]
permissions: {}
jobs:
release:
runs-on: ubuntu-latest
environment: pypi
permissions:
contents: write # create the GitHub release and attach assets
id-token: write # PyPI trusted publishing (OIDC)
outputs:
version: ${{ steps.release.outputs.version }}
released: ${{ steps.published.outputs.released }}
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
with:
enable-cache: false
- name: Check release version
id: release
env:
TAG: ${{ github.event.release.tag_name }}
run: |
version=$(uv version --short)
if [ "${version}" != "${TAG}" ]; then
echo "::error::Release ${TAG} does not match the package version ${version}"
exit 1
fi
echo "version=${version}" >> "$GITHUB_OUTPUT"
- name: Build package
run: uv build
# Package plus locked runtime dependencies only, so the SBOM matches what
# users install from PyPI rather than the dev/test toolchain.
- name: Install runtime environment
run: uv sync --frozen --no-default-groups --no-editable
- uses: anchore/sbom-action/download-syft@66cbf4bc1f1c0d2edc94016e65bc221b6bb0ad6c # v0.24.3
id: syft
# Scan site-packages only; .venv/bin links to the interpreter outside the env.
# SPDX for the release page, CycloneDX 1.6 for DependencyTrack.
- name: Generate SBOM
env:
SYFT: ${{ steps.syft.outputs.cmd }}
SYFT_FILE_METADATA_SELECTION: none
VERSION: ${{ steps.release.outputs.version }}
run: |
set -euo pipefail
"$SYFT" dir:.venv/lib \
--source-name django-postcode-lookup \
--source-version "${VERSION}" \
-o spdx-json=django-postcode-lookup.spdx.json \
-o cyclonedx-json@1.6=django-postcode-lookup.raw.cdx.json
# The package's own entry points at the local checkout (file://); drop it.
jq '.components |= map(if .externalReferences then .externalReferences |= map(select(.url | startswith("file://") | not)) else . end)' \
django-postcode-lookup.raw.cdx.json > django-postcode-lookup.cdx.json
- name: Publish package
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
- name: Upload release assets
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.event.release.tag_name }}
run: |
gh release upload "${TAG}" \
dist/* django-postcode-lookup.spdx.json django-postcode-lookup.cdx.json
- name: Mark release published
id: published
run: echo "released=true" >> "$GITHUB_OUTPUT"
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
if: steps.published.outputs.released == 'true'
with:
name: sbom-cyclonedx
path: django-postcode-lookup.cdx.json
retention-days: 7
# Separate job so the DT key is never present while repo code runs
# (uv build / uv sync above execute the build backend).
dependencytrack:
needs: release
if: needs.release.outputs.released == 'true'
runs-on: ubuntu-latest
permissions: {}
steps:
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: sbom-cyclonedx
# Each release becomes a version under the "oss/python/django-postcode-lookup"
# library container (OSS > OSS Python), which rolls up the latest version.
- name: Upload SBOM to DependencyTrack
env:
DT_API_KEY: ${{ secrets.DEPENDENCYTRACK_OSS_APIKEY }}
DT_URL: https://dependencytrack-api.labdigital.nl:8443
PROJECT: oss/python/django-postcode-lookup
VERSION: ${{ needs.release.outputs.version }}
run: |
set -euo pipefail
if [ -z "${DT_API_KEY}" ]; then
echo "::error::DEPENDENCYTRACK_OSS_APIKEY is not available to this repo"
exit 1
fi
curl -sS --fail-with-body -X POST "${DT_URL}/api/v1/bom" \
-H "X-Api-Key: ${DT_API_KEY}" \
-F "autoCreate=true" \
-F "projectName=${PROJECT}" \
-F "projectVersion=${VERSION}" \
-F "parentName=${PROJECT}" \
-F "isLatest=true" \
-F "bom=@django-postcode-lookup.cdx.json"