Skip to content

Commit c86ee5a

Browse files
committed
fix: optimize release workflow with efficient artifact management
- Replace manual Docker tar operations with direct output naming - Use python-semantic-release/publish-action for streamlined Python package uploads - Add docker/metadata-action with auto-detected repository metadata - Implement convenience Git tags matching Docker tagging strategy - Remove redundant Docker file operations and metadata overrides - Fix Dockerfile PATH issues for poetry installation
1 parent 21d0978 commit c86ee5a

File tree

2 files changed

+108
-71
lines changed

2 files changed

+108
-71
lines changed

.github/workflows/release.yaml

Lines changed: 104 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,118 +7,152 @@ on:
77
workflow_dispatch:
88

99
permissions:
10-
contents: write # Required for creating releases
11-
issues: write
12-
pull-requests: write
13-
statuses: write
14-
checks: write
15-
id-token: write # Required for generating build attestations
16-
17-
concurrency:
18-
group: release-workflow
19-
cancel-in-progress: true
10+
contents: read
2011

2112
jobs:
22-
semantic-release:
23-
if: ${{ github.ref == 'refs/heads/main' }}
13+
release:
2414
runs-on: ubuntu-latest
15+
concurrency:
16+
group: ${{ github.workflow }}-release-${{ github.ref_name }}
17+
cancel-in-progress: false
18+
19+
permissions:
20+
contents: write
21+
issues: write
22+
pull-requests: write
23+
24+
outputs:
25+
released: ${{ steps.release.outputs.released }}
26+
version: ${{ steps.release.outputs.version }}
27+
tag: ${{ steps.release.outputs.tag }}
28+
2529
steps:
26-
- uses: actions/checkout@v4
30+
- name: Setup | Checkout Repository
31+
uses: actions/checkout@v4
2732
with:
2833
fetch-depth: 0
2934
token: ${{ secrets.GITHUB_TOKEN }}
30-
- name: Set up Python
35+
36+
- name: Setup | Python
3137
uses: actions/setup-python@v5
3238
with:
3339
python-version: 3.11
34-
- name: Install Dependencies
40+
41+
- name: Setup | Install Dependencies
3542
run: |
3643
pip install poetry
3744
poetry install --with dev
38-
- name: Configure Git for semantic-release
39-
run: |
40-
git config --global user.name "github-actions[bot]"
41-
git config --global user.email "github-actions[bot]@users.noreply.github.com"
42-
git config --global commit.gpgsign false # Disable signing for automated commits
43-
- name: Python Semantic Release
45+
46+
- name: Action | Semantic Version Release
47+
id: release
4448
uses: python-semantic-release/python-semantic-release@v10.0.2
4549
with:
4650
github_token: ${{ secrets.GITHUB_TOKEN }}
47-
changelog: true # Generate changelog
48-
vcs_release: true # Create a release on GitHub
49-
tag: true # Tag the release
50-
push: true # Push changes back to the repository
51-
commit: true # Commit changes
51+
git_committer_name: "github-actions[bot]"
52+
git_committer_email: "github-actions[bot]@users.noreply.github.com"
53+
54+
- name: Publish | Upload to GitHub Release Assets
55+
uses: python-semantic-release/publish-action@v10.0.2
56+
if: steps.release.outputs.released == 'true'
57+
with:
58+
github_token: ${{ secrets.GITHUB_TOKEN }}
59+
tag: ${{ steps.release.outputs.tag }}
60+
61+
- name: Publish to TestPyPI
62+
if: steps.release.outputs.released == 'true'
63+
env:
64+
POETRY_PYPI_TOKEN_TESTPYPI: ${{ secrets.TEST_PYPI_API_TOKEN }}
65+
run: |
66+
poetry config repositories.testpypi https://test.pypi.org/legacy/
67+
poetry publish --repository testpypi
68+
69+
- name: Create convenience Git tags
70+
if: steps.release.outputs.released == 'true'
71+
run: |
72+
# Extract version components for convenience tagging
73+
VERSION=${{ steps.release.outputs.version }}
74+
MAJOR=$(echo "$VERSION" | cut -d. -f1)
75+
MINOR=$(echo "$VERSION" | cut -d. -f2)
76+
77+
# Create/update convenience tags to match Docker tagging strategy
78+
git tag -f "v$MAJOR" ${{ steps.release.outputs.tag }}
79+
git tag -f "v$MAJOR.$MINOR" ${{ steps.release.outputs.tag }}
80+
81+
# Push convenience tags
82+
git push origin "v$MAJOR" --force
83+
git push origin "v$MAJOR.$MINOR" --force
5284
85+
echo "Created convenience tags: v$MAJOR, v$MAJOR.$MINOR"
5386
5487
sbom-generation:
55-
needs: semantic-release # Ensure this runs after the semantic-release job
56-
if: ${{ github.ref == 'refs/heads/main' }}
88+
needs: release
89+
if: needs.release.outputs.released == 'true'
5790
runs-on: ubuntu-latest
5891
permissions:
5992
contents: write
6093
actions: read
6194
security-events: write
95+
6296
steps:
6397
- uses: actions/checkout@v4
6498
with:
6599
fetch-depth: 0
66-
ref: ${{ github.head_ref || github.ref_name }}
67-
- name: Get version
68-
id: version
69-
run: |
70-
# Get version from pyproject.toml after semantic-release updated it
71-
VERSION=$(grep '^version =' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
72-
echo "version=$VERSION" >> $GITHUB_OUTPUT
73-
echo "Version: $VERSION"
100+
ref: ${{ needs.release.outputs.tag }}
101+
74102
- name: Generate SBOM
75103
uses: anchore/sbom-action@v0.17.6
76104
with:
77-
path: . # Generate SBOM for the entire repository
78-
artifact-name: sbom.spdx.json # Name of the generated SBOM file
79-
format: spdx-json # Use SPDX format for SBOM
80-
dependency-snapshot: true # Include dependency snapshot (non-breaking warning)
81-
upload-release-assets: true # Automatically upload to GitHub release
105+
path: .
106+
artifact-name: sbom.spdx.json
107+
format: spdx-json
108+
dependency-snapshot: true
109+
upload-release-assets: true
82110
github-token: ${{ secrets.GITHUB_TOKEN }}
83111

84-
publish:
85-
needs: semantic-release
86-
if: ${{ github.ref == 'refs/heads/main' }}
112+
docker-artifacts:
113+
needs: release
114+
if: needs.release.outputs.released == 'true'
87115
runs-on: ubuntu-latest
116+
permissions:
117+
contents: write
118+
88119
steps:
89120
- uses: actions/checkout@v4
90121
with:
91122
fetch-depth: 0
92-
ref: ${{ github.head_ref || github.ref_name }}
93-
- name: Get version
94-
id: version
95-
run: |
96-
# Get version from pyproject.toml after semantic-release updated it
97-
VERSION=$(grep '^version =' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
98-
echo "version=$VERSION" >> $GITHUB_OUTPUT
99-
echo "Version: $VERSION"
123+
ref: ${{ needs.release.outputs.tag }}
124+
100125
- name: Set up Docker Buildx
101126
uses: docker/setup-buildx-action@v3
102-
- name: Build Docker image as tar
103-
run: |
104-
docker build -t network-reputation-check:v${{ steps.version.outputs.version }} .
105-
docker save network-reputation-check:v${{ steps.version.outputs.version }} -o network-reputation-check-v${{ steps.version.outputs.version }}.tar
127+
128+
- name: Extract metadata
129+
id: meta
130+
uses: docker/metadata-action@v5
131+
with:
132+
images: network-reputation-check
133+
tags: |
134+
type=semver,pattern={{version}},value=${{ needs.release.outputs.version }}
135+
type=semver,pattern={{major}}.{{minor}},value=${{ needs.release.outputs.version }}
136+
type=semver,pattern={{major}},value=${{ needs.release.outputs.version }}
137+
type=raw,value=latest
138+
labels: |
139+
org.opencontainers.image.title=Network Reputation Check Action
140+
org.opencontainers.image.description=${{ github.event.repository.description }}
141+
142+
- name: Build Docker image
143+
id: build
144+
uses: docker/build-push-action@v6
145+
with:
146+
context: .
147+
push: false
148+
tags: ${{ steps.meta.outputs.tags }}
149+
labels: ${{ steps.meta.outputs.labels }}
150+
outputs: type=docker,dest=network-reputation-check-${{ needs.release.outputs.version }}.tar
151+
106152
- name: Upload Docker tar to GitHub release
107153
uses: softprops/action-gh-release@v2
108154
with:
109-
tag_name: v${{ steps.version.outputs.version }}
110-
files: network-reputation-check-v${{ steps.version.outputs.version }}.tar
155+
tag_name: ${{ needs.release.outputs.tag }}
156+
files: network-reputation-check-${{ needs.release.outputs.version }}.tar
111157
draft: false
112158
prerelease: false
113-
- name: Set up Python for TestPyPI publishing
114-
uses: actions/setup-python@v5
115-
with:
116-
python-version: 3.11
117-
- name: Install Poetry and publish to TestPyPI
118-
env:
119-
POETRY_PYPI_TOKEN_TESTPYPI: ${{ secrets.TEST_PYPI_API_TOKEN }}
120-
run: |
121-
pip install poetry
122-
poetry config repositories.testpypi https://test.pypi.org/legacy/
123-
poetry build # Build fresh since semantic-release built in different environment
124-
poetry publish --repository testpypi

Dockerfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ RUN adduser --disabled-password --gecos "" appuser \
77
&& chown -R appuser:appuser /app
88
USER appuser
99

10+
# Add .local/bin to PATH for poetry
11+
ENV PATH="/home/appuser/.local/bin:$PATH"
12+
1013
# Install poetry and dependencies as non-root user
1114
RUN pip install --no-cache-dir poetry \
12-
&& poetry install --no-dev
15+
&& poetry install --without dev
1316

1417
ENTRYPOINT ["poetry", "run", "reputation-check"]

0 commit comments

Comments
 (0)