From abb841028bf73a395c6426179439e8b39f2b5e14 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:05:36 +0200 Subject: [PATCH 01/20] refactor workflows into reusable workflows --- .github/workflows/main-workflow.yml | 35 +++++++++++++++++++ .../{cd-dev.yml => reusable-cd-dev.yml} | 4 +-- .github/workflows/{ci.yml => reusable-ci.yml} | 35 +++++++++++++------ .../workflows/{docs.yml => reusable-docs.yml} | 10 +----- .../{security.yml => reusable-security.yml} | 31 +++++++++++----- .github/workflows/schedule-security.yml | 11 ++++++ 6 files changed, 96 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/main-workflow.yml rename .github/workflows/{cd-dev.yml => reusable-cd-dev.yml} (96%) rename .github/workflows/{ci.yml => reusable-ci.yml} (65%) rename .github/workflows/{docs.yml => reusable-docs.yml} (79%) rename .github/workflows/{security.yml => reusable-security.yml} (63%) create mode 100644 .github/workflows/schedule-security.yml diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml new file mode 100644 index 0000000..5641b1f --- /dev/null +++ b/.github/workflows/main-workflow.yml @@ -0,0 +1,35 @@ +name: Main Workflow + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +jobs: + ci: + uses: ./.github/workflows/reusable-ci.yml + + security: + uses: ./.github/workflows/reusable-security.yml + + docs: + # Only run docs if documentation files change + if: | + contains(github.event.head_commit.modified, 'docs/') || + contains(github.event.head_commit.modified, 'README.md') || + contains(github.event.head_commit.modified, 'CONTRIBUTING.md') || + contains(github.event.head_commit.modified, 'mkdocs.yml') + uses: ./.github/workflows/reusable-docs.yml + + cd-dev: + needs: [ci, security, docs] + if: | + needs.ci.outputs.overall-success == 'true' && + needs.security.outputs.overall-success == 'true' && + needs.docs.outputs.success == 'true' && + (contains(github.event.head_commit.modified, 'src/') || + contains(github.event.head_commit.modified, 'pyproject.toml')) + uses: ./.github/workflows/reusable-cd-dev.yml + secrets: inherit diff --git a/.github/workflows/cd-dev.yml b/.github/workflows/reusable-cd-dev.yml similarity index 96% rename from .github/workflows/cd-dev.yml rename to .github/workflows/reusable-cd-dev.yml index b4eb475..4b15ace 100644 --- a/.github/workflows/cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -1,9 +1,7 @@ name: CD - Dev Publishing on: - push: - branches: [ main ] - workflow_dispatch: + workflow_call: jobs: publish-dev: diff --git a/.github/workflows/ci.yml b/.github/workflows/reusable-ci.yml similarity index 65% rename from .github/workflows/ci.yml rename to .github/workflows/reusable-ci.yml index e32b6ef..03d08ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/reusable-ci.yml @@ -1,15 +1,11 @@ -name: Lint and Type Check +name: Lint, Checks, Automated Tests, Build Test on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -# Define reusable steps as anchors -defaults: - run: - shell: bash + workflow_call: + outputs: + overall-success: + description: "CI all checks passed" + value: ${{ jobs.aggregate-results.outputs.overall-success }} jobs: ruff-check: @@ -90,3 +86,22 @@ jobs: - name: Installation dry run run: pip install dist/*.whl + + aggregate-results: + needs: [ruff-check, ruff-format, mypy, unit-tests, build-package ] + runs-on: ubuntu-latest + outputs: + overall-success: ${{ steps.aggregate.outputs.overall-success }} + steps: + - name: Check if all jobs passed + id: aggregate + run: | + if [[ "${{ needs.ruff-check.result }}" == "success" && \ + "${{ needs.ruff-format.result }}" == "success" && \ + "${{ needs.mypy.result }}" == "success" && \ + "${{ needs.unit-tests.result }}" == "success" && \ + "${{ needs.build-package.result }}" == "success" ]]; then + echo "overall-success=true" >> $GITHUB_OUTPUT + else + echo "overall-success=false" >> $GITHUB_OUTPUT + fi diff --git a/.github/workflows/docs.yml b/.github/workflows/reusable-docs.yml similarity index 79% rename from .github/workflows/docs.yml rename to .github/workflows/reusable-docs.yml index e899230..604d4be 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -1,15 +1,7 @@ name: Deploy Documentation on: - workflow_dispatch: - push: - branches: [ main ] - paths: - - 'docs/**' - - 'mkdocs.yml' - - 'README.md' - - 'CONTRIBUTING.md' - - '.github/workflows/docs.yml' + workflow_call: permissions: contents: write diff --git a/.github/workflows/security.yml b/.github/workflows/reusable-security.yml similarity index 63% rename from .github/workflows/security.yml rename to .github/workflows/reusable-security.yml index 987641c..9a8422b 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/reusable-security.yml @@ -1,14 +1,11 @@ name: Security Scan on: - schedule: - # Run daily at 6 AM UTC - - cron: '0 6 * * *' - workflow_dispatch: # Allow manual triggers - pull_request: - branches: [ main ] - push: - branches: [ main ] + workflow_call: + outputs: + overall-success: + description: "Security all checks passed" + value: ${{ jobs.aggregate-results.outputs.overall-success }} jobs: safety-scan: @@ -75,3 +72,21 @@ jobs: uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + aggregate-results: + needs: [safety-scan, bandit-scan, codeql-scan, secret-scan] + runs-on: ubuntu-latest + outputs: + overall-success: ${{ steps.aggregate.outputs.overall-success }} + steps: + - name: Check if all jobs passed + id: aggregate + run: | + if [[ "${{ needs.safety-scan.result }}" == "success" && \ + "${{ needs.bandit-scan.result }}" == "success" && \ + "${{ needs.codeql-scan.result }}" == "success" && \ + "${{ needs.secret-scan.result }}" == "success" ]]; then + echo "overall-success=true" >> $GITHUB_OUTPUT + else + echo "overall-success=false" >> $GITHUB_OUTPUT + fi diff --git a/.github/workflows/schedule-security.yml b/.github/workflows/schedule-security.yml new file mode 100644 index 0000000..bb858ac --- /dev/null +++ b/.github/workflows/schedule-security.yml @@ -0,0 +1,11 @@ +name: Scheduled Security Scan + +on: + schedule: + # Run daily at 6 AM UTC + - cron: '0 6 * * *' + workflow_dispatch: # Allow manual triggers + +jobs: + security: + uses: ./.github/workflows/reusable-security.yml From a07499d5a9dce3231198609decd3403359e3af2a Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:14:44 +0200 Subject: [PATCH 02/20] add permissions for security scan --- .github/workflows/schedule-security.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/schedule-security.yml b/.github/workflows/schedule-security.yml index bb858ac..671b7c8 100644 --- a/.github/workflows/schedule-security.yml +++ b/.github/workflows/schedule-security.yml @@ -6,6 +6,10 @@ on: - cron: '0 6 * * *' workflow_dispatch: # Allow manual triggers +permissions: + actions: read + security-events: write + jobs: security: uses: ./.github/workflows/reusable-security.yml From 56c5abf2231e20d3a09c19ef143f7cecca82cdc6 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:28:40 +0200 Subject: [PATCH 03/20] fix permissions issue --- .github/workflows/main-workflow.yml | 9 +++++++++ .github/workflows/schedule-security.yml | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index 5641b1f..5cd4ebd 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -12,9 +12,18 @@ jobs: uses: ./.github/workflows/reusable-ci.yml security: + permissions: + security-events: write + actions: read + contents: read + packages: read uses: ./.github/workflows/reusable-security.yml docs: + permissions: + contents: write + pages: write + id-token: write # Only run docs if documentation files change if: | contains(github.event.head_commit.modified, 'docs/') || diff --git a/.github/workflows/schedule-security.yml b/.github/workflows/schedule-security.yml index 671b7c8..d1fdd8b 100644 --- a/.github/workflows/schedule-security.yml +++ b/.github/workflows/schedule-security.yml @@ -6,10 +6,11 @@ on: - cron: '0 6 * * *' workflow_dispatch: # Allow manual triggers -permissions: - actions: read - security-events: write - jobs: security: + permissions: + security-events: write + actions: read + contents: read + packages: read uses: ./.github/workflows/reusable-security.yml From ee32bec01cf1cd03f95fbd50213be55aa75ff6d4 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:44:26 +0200 Subject: [PATCH 04/20] fix docs check if skipped --- .github/workflows/main-workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index 5cd4ebd..33af428 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -37,7 +37,7 @@ jobs: if: | needs.ci.outputs.overall-success == 'true' && needs.security.outputs.overall-success == 'true' && - needs.docs.outputs.success == 'true' && + (needs.docs.result == 'success' || needs.docs.result == 'skipped') && (contains(github.event.head_commit.modified, 'src/') || contains(github.event.head_commit.modified, 'pyproject.toml')) uses: ./.github/workflows/reusable-cd-dev.yml From 7e57ea011280ef61f33fcbcd00888f8c173cae12 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 23:05:40 +0200 Subject: [PATCH 05/20] add names to jobs; add debug info --- .github/workflows/main-workflow.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index 33af428..d17b600 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -9,9 +9,11 @@ on: jobs: ci: + name: CI lint, type, test, build uses: ./.github/workflows/reusable-ci.yml security: + name: Security scans permissions: security-events: write actions: read @@ -20,6 +22,7 @@ jobs: uses: ./.github/workflows/reusable-security.yml docs: + name: Deploy Documentation permissions: contents: write pages: write @@ -33,12 +36,26 @@ jobs: uses: ./.github/workflows/reusable-docs.yml cd-dev: + name: CD Dev Publishing needs: [ci, security, docs] if: | needs.ci.outputs.overall-success == 'true' && needs.security.outputs.overall-success == 'true' && (needs.docs.result == 'success' || needs.docs.result == 'skipped') && (contains(github.event.head_commit.modified, 'src/') || - contains(github.event.head_commit.modified, 'pyproject.toml')) + contains(github.event.head_commit.modified, 'pyproject.toml')) uses: ./.github/workflows/reusable-cd-dev.yml secrets: inherit + + debug-deps: + runs-on: ubuntu-latest + needs: [ci, security, docs] + steps: + - name: Debug outputs + run: | + echo "CI result: ${{ needs.ci.result }}" + echo "CI overall-success: ${{ needs.ci.outputs.overall-success }}" + echo "Security result: ${{ needs.security.result }}" + echo "Security overall-success: ${{ needs.security.outputs.overall-success }}" + echo "Docs result: ${{ needs.docs.result }}" + echo "Modified files: ${{ join(github.event.head_commit.modified, ', ') }}" From b38a881b7367f27b396b629fc83d12561bc291aa Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 23:17:48 +0200 Subject: [PATCH 06/20] add !cancelled() to avoid skipping the job --- .github/workflows/main-workflow.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index d17b600..15e11e7 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -39,6 +39,7 @@ jobs: name: CD Dev Publishing needs: [ci, security, docs] if: | + !cancelled() && needs.ci.outputs.overall-success == 'true' && needs.security.outputs.overall-success == 'true' && (needs.docs.result == 'success' || needs.docs.result == 'skipped') && @@ -52,6 +53,7 @@ jobs: needs: [ci, security, docs] steps: - name: Debug outputs + if: ${{ always() }} run: | echo "CI result: ${{ needs.ci.result }}" echo "CI overall-success: ${{ needs.ci.outputs.overall-success }}" From c480392829366442d63c142b7e38d3778af6756a Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 23:37:51 +0200 Subject: [PATCH 07/20] test debug info --- .github/workflows/main-workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index 15e11e7..d61ca29 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -53,7 +53,7 @@ jobs: needs: [ci, security, docs] steps: - name: Debug outputs - if: ${{ always() }} + if: always() run: | echo "CI result: ${{ needs.ci.result }}" echo "CI overall-success: ${{ needs.ci.outputs.overall-success }}" From 0c784b21e5bd6da945274184936820ae4e2e8c2b Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 23:41:18 +0200 Subject: [PATCH 08/20] remove if condition for testing purposes --- .github/workflows/main-workflow.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index d61ca29..b731b62 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -53,7 +53,6 @@ jobs: needs: [ci, security, docs] steps: - name: Debug outputs - if: always() run: | echo "CI result: ${{ needs.ci.result }}" echo "CI overall-success: ${{ needs.ci.outputs.overall-success }}" From 7c34629fc14cc03e85b0fc159ee97d47fba7f87f Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Wed, 19 Nov 2025 23:51:34 +0200 Subject: [PATCH 09/20] remove dependency on docs --- .github/workflows/main-workflow.yml | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index b731b62..71630a8 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -2,9 +2,9 @@ name: Main Workflow on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] workflow_dispatch: jobs: @@ -27,8 +27,7 @@ jobs: contents: write pages: write id-token: write - # Only run docs if documentation files change - if: | + if: | # Only run docs if documentation files change contains(github.event.head_commit.modified, 'docs/') || contains(github.event.head_commit.modified, 'README.md') || contains(github.event.head_commit.modified, 'CONTRIBUTING.md') || @@ -37,26 +36,11 @@ jobs: cd-dev: name: CD Dev Publishing - needs: [ci, security, docs] + needs: [ci, security] if: | - !cancelled() && needs.ci.outputs.overall-success == 'true' && needs.security.outputs.overall-success == 'true' && - (needs.docs.result == 'success' || needs.docs.result == 'skipped') && (contains(github.event.head_commit.modified, 'src/') || contains(github.event.head_commit.modified, 'pyproject.toml')) uses: ./.github/workflows/reusable-cd-dev.yml secrets: inherit - - debug-deps: - runs-on: ubuntu-latest - needs: [ci, security, docs] - steps: - - name: Debug outputs - run: | - echo "CI result: ${{ needs.ci.result }}" - echo "CI overall-success: ${{ needs.ci.outputs.overall-success }}" - echo "Security result: ${{ needs.security.result }}" - echo "Security overall-success: ${{ needs.security.outputs.overall-success }}" - echo "Docs result: ${{ needs.docs.result }}" - echo "Modified files: ${{ join(github.event.head_commit.modified, ', ') }}" From 4a1694c24f5d891a00cd291b2f37fc198d5deb42 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Thu, 20 Nov 2025 00:02:21 +0200 Subject: [PATCH 10/20] add mock change to pyproject.toml --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 399fc8b..01f82bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,6 +2,7 @@ requires = ["setuptools>=69.4.2", "wheel>=0.44.0", "setuptools-scm>=8.1.0"] build-backend = "setuptools.build_meta" + [tool.setuptools_scm] write_to = "src/tftp_router_flasher/_version.py" # Create version file version_scheme = "no-guess-dev" # Increment patch for dev From dbd15976e3ca93a0a80e2c1e1747c5e50185ef1c Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Thu, 20 Nov 2025 00:07:28 +0200 Subject: [PATCH 11/20] remove whole if condition --- .github/workflows/main-workflow.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index 71630a8..4c4cc5b 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -37,10 +37,5 @@ jobs: cd-dev: name: CD Dev Publishing needs: [ci, security] - if: | - needs.ci.outputs.overall-success == 'true' && - needs.security.outputs.overall-success == 'true' && - (contains(github.event.head_commit.modified, 'src/') || - contains(github.event.head_commit.modified, 'pyproject.toml')) uses: ./.github/workflows/reusable-cd-dev.yml secrets: inherit From debccd4d9a7f11299ffe6b67ea280a91e4f355dc Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Thu, 20 Nov 2025 00:12:35 +0200 Subject: [PATCH 12/20] add back if with !cancelled() --- .github/workflows/main-workflow.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main-workflow.yml b/.github/workflows/main-workflow.yml index 4c4cc5b..afb5384 100644 --- a/.github/workflows/main-workflow.yml +++ b/.github/workflows/main-workflow.yml @@ -36,6 +36,7 @@ jobs: cd-dev: name: CD Dev Publishing - needs: [ci, security] + needs: [ci, security, docs] + if: ${{ !cancelled() }} uses: ./.github/workflows/reusable-cd-dev.yml secrets: inherit From 28d450dd480690e42ef262505d97852ab155a945 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 21:20:49 +0200 Subject: [PATCH 13/20] test.pypi.org: delete version before test --- .github/workflows/reusable-cd-dev.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index 4b15ace..c877bf4 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -3,6 +3,10 @@ name: CD - Dev Publishing on: workflow_call: +env: + TEST_PYPI_UPLOAD_URL: "https://test.pypi.org/legacy/" + TEST_PYPI_INSTALL_URL: "https://test.pypi.org/simple/" + jobs: publish-dev: runs-on: ubuntu-latest @@ -11,6 +15,24 @@ jobs: - name: Checkout code uses: actions/checkout@v5 + - name: Extract package info + id: package-info + run: | + PACKAGE_NAME=$(python -c "import tomli; print(tomli.load(open('pyproject.toml', 'rb'))['project']['name'])") + VERSION=$(python -c "import tomli; print(tomli.load(open('pyproject.toml', 'rb'))['project']['version'])") + echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_ENV + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Delete existing package from Test PyPI (if exists) + run: | + # This will fail gracefully if the package doesn't exist + curl -f -X DELETE \ + -H "Authorization: token ${{ secrets.TEST_PYPI_API_TOKEN }}" \ + -d ":action=remove" \ + -d "name=${{ env.PACKAGE_NAME }}" \ + -d "version=${{ env.VERSION }}" \ + "${TEST_PYPI_UPLOAD_URL}" || echo "Package didn't exist or delete failed - continuing" + - name: Calculate dev version id: version shell: bash @@ -40,7 +62,7 @@ jobs: - name: Build and publish to TestPyPI uses: ./.github/actions/build-and-publish with: - pypi-upload-url: 'https://test.pypi.org/legacy/' - pypi-install-url: 'https://test.pypi.org/simple/' + pypi-upload-url: ${{ TEST_PYPI_UPLOAD_URL }} + pypi-install-url: ${{ TEST_PYPI_INSTALL_URL }} version-override: ${{ steps.version.outputs.version }} pypi-token: ${{ secrets.TEST_PYPI_API_TOKEN }} From 57cfa8a32936be9ccdea6c01ad66e4f0828bfe18 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 21:24:26 +0200 Subject: [PATCH 14/20] missing env. prefix --- .github/workflows/reusable-cd-dev.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index c877bf4..96e284b 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -31,7 +31,7 @@ jobs: -d ":action=remove" \ -d "name=${{ env.PACKAGE_NAME }}" \ -d "version=${{ env.VERSION }}" \ - "${TEST_PYPI_UPLOAD_URL}" || echo "Package didn't exist or delete failed - continuing" + "${env.TEST_PYPI_UPLOAD_URL}" || echo "Package didn't exist or delete failed - continuing" - name: Calculate dev version id: version @@ -62,7 +62,7 @@ jobs: - name: Build and publish to TestPyPI uses: ./.github/actions/build-and-publish with: - pypi-upload-url: ${{ TEST_PYPI_UPLOAD_URL }} - pypi-install-url: ${{ TEST_PYPI_INSTALL_URL }} + pypi-upload-url: ${{ env.TEST_PYPI_UPLOAD_URL }} + pypi-install-url: ${{ env.TEST_PYPI_INSTALL_URL }} version-override: ${{ steps.version.outputs.version }} pypi-token: ${{ secrets.TEST_PYPI_API_TOKEN }} From f57b89070579cfd2e12910f5fc42b36d9d57b2fa Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 21:30:22 +0200 Subject: [PATCH 15/20] use built-in package tomllib instead of tomli --- .github/workflows/reusable-cd-dev.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index 96e284b..a5818a2 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -18,11 +18,10 @@ jobs: - name: Extract package info id: package-info run: | - PACKAGE_NAME=$(python -c "import tomli; print(tomli.load(open('pyproject.toml', 'rb'))['project']['name'])") - VERSION=$(python -c "import tomli; print(tomli.load(open('pyproject.toml', 'rb'))['project']['version'])") + PACKAGE_NAME=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])") + VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])") echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_ENV echo "VERSION=$VERSION" >> $GITHUB_ENV - - name: Delete existing package from Test PyPI (if exists) run: | # This will fail gracefully if the package doesn't exist From 909978d224a2440c16fb659c39744e81f106727b Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 21:43:07 +0200 Subject: [PATCH 16/20] use dynamic version from setuptools_scm --- .github/workflows/reusable-cd-dev.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index a5818a2..831a608 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -15,11 +15,16 @@ jobs: - name: Checkout code uses: actions/checkout@v5 + - uses: ./.github/actions/setup-python + with: + python-version: "3.11" # minimum supported version + requirements: ".[build]" + - name: Extract package info id: package-info run: | PACKAGE_NAME=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])") - VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])") + VERSION=$(python -c "import setuptools_scm; print(setuptools_scm.get_version())") echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_ENV echo "VERSION=$VERSION" >> $GITHUB_ENV - name: Delete existing package from Test PyPI (if exists) From 4d74e70b6558437caeb2969e05f8bb2dd1143be1 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 21:49:30 +0200 Subject: [PATCH 17/20] fix wrong brackets on env. variable --- .github/workflows/reusable-cd-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index 831a608..d099ded 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -35,7 +35,7 @@ jobs: -d ":action=remove" \ -d "name=${{ env.PACKAGE_NAME }}" \ -d "version=${{ env.VERSION }}" \ - "${env.TEST_PYPI_UPLOAD_URL}" || echo "Package didn't exist or delete failed - continuing" + "${{ env.TEST_PYPI_UPLOAD_URL }}" || echo "Package didn't exist or delete failed - continuing" - name: Calculate dev version id: version From 29941e9fdec7590dd861eaf5a8f2f97fa9e46160 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 22:00:53 +0200 Subject: [PATCH 18/20] replace setuptools_scm versioning with LATEST_TAG --- .github/workflows/reusable-cd-dev.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index d099ded..40319ba 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -24,7 +24,8 @@ jobs: id: package-info run: | PACKAGE_NAME=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])") - VERSION=$(python -c "import setuptools_scm; print(setuptools_scm.get_version())") + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0") + VERSION=${LATEST_TAG#v} echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_ENV echo "VERSION=$VERSION" >> $GITHUB_ENV - name: Delete existing package from Test PyPI (if exists) From 22ea07d4d3add891b39d3a7011651d9a33cf55b2 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 22:07:20 +0200 Subject: [PATCH 19/20] show debug info --- .github/workflows/reusable-cd-dev.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index 40319ba..c7d355a 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -28,7 +28,10 @@ jobs: VERSION=${LATEST_TAG#v} echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_ENV echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Delete existing package from Test PyPI (if exists) + env: + ACTIONS_STEP_DEBUG: true run: | # This will fail gracefully if the package doesn't exist curl -f -X DELETE \ @@ -36,7 +39,7 @@ jobs: -d ":action=remove" \ -d "name=${{ env.PACKAGE_NAME }}" \ -d "version=${{ env.VERSION }}" \ - "${{ env.TEST_PYPI_UPLOAD_URL }}" || echo "Package didn't exist or delete failed - continuing" + "${{ env.TEST_PYPI_UPLOAD_URL }}" - name: Calculate dev version id: version From ef5007edb5547cfdd1511bd1cd342be7ab90d8b0 Mon Sep 17 00:00:00 2001 From: Ghost <166657596+vr-ski@users.noreply.github.com> Date: Mon, 24 Nov 2025 22:21:33 +0200 Subject: [PATCH 20/20] use timestamp for dev versions --- .github/workflows/reusable-cd-dev.yml | 29 ++------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/.github/workflows/reusable-cd-dev.yml b/.github/workflows/reusable-cd-dev.yml index c7d355a..b62ff57 100644 --- a/.github/workflows/reusable-cd-dev.yml +++ b/.github/workflows/reusable-cd-dev.yml @@ -15,32 +15,6 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - - uses: ./.github/actions/setup-python - with: - python-version: "3.11" # minimum supported version - requirements: ".[build]" - - - name: Extract package info - id: package-info - run: | - PACKAGE_NAME=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])") - LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0") - VERSION=${LATEST_TAG#v} - echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_ENV - echo "VERSION=$VERSION" >> $GITHUB_ENV - - - name: Delete existing package from Test PyPI (if exists) - env: - ACTIONS_STEP_DEBUG: true - run: | - # This will fail gracefully if the package doesn't exist - curl -f -X DELETE \ - -H "Authorization: token ${{ secrets.TEST_PYPI_API_TOKEN }}" \ - -d ":action=remove" \ - -d "name=${{ env.PACKAGE_NAME }}" \ - -d "version=${{ env.VERSION }}" \ - "${{ env.TEST_PYPI_UPLOAD_URL }}" - - name: Calculate dev version id: version shell: bash @@ -62,7 +36,8 @@ jobs: PATCH=0 fi - DEV_VERSION="${MAJOR}.${MINOR}.${PATCH}.dev${{ github.run_number }}" + TIMESTAMP=$(date +%Y%m%d%H%M%S) + DEV_VERSION="${MAJOR}.${MINOR}.${PATCH}.dev${TIMESTAMP}" echo "Dev version: $DEV_VERSION" echo "version=$DEV_VERSION" >> $GITHUB_OUTPUT