Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Preserve source fingerprints and generated text references on every checkout.
* text=auto eol=lf
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.zip binary
*.whl binary
*.gz binary
26 changes: 20 additions & 6 deletions .github/workflows/documentation-artifact.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
name: Documentation preview artifact
name: Documentation validation
on:
pull_request:
workflow_dispatch:
workflow_call:
inputs:
pages_artifact:
description: Upload the validated site for the master-only Pages deploy
type: boolean
default: false
permissions:
contents: read
jobs:
build:
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
- run: python -m pip install -r requirements-docs.txt
- run: python -m pip install -e .
- run: python tools/check_architecture_docs.py --examples --getting-started --api-reference --tutorials --showcase --website
- run: python -m mkdocs build --strict
- run: python tools/check_site.py --site-dir site
- run: python tools/check_architecture_docs.py --examples --getting-started --api-reference --tutorials --showcase --website
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: documentation-preview
path: site
if-no-files-found: error
retention-days: 7
- name: Upload checked Pages artifact
if: inputs.pages_artifact && github.repository == 'AlexMarinescu/pyGameMath' && github.ref == 'refs/heads/master'
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: site
88 changes: 88 additions & 0 deletions .github/workflows/github-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: GitHub release preparation
on:
workflow_dispatch:
inputs:
commit_sha:
description: Full final reviewed master commit SHA
required: true
type: string
validation_run_id:
description: Successful manual candidate-validation run for that exact commit
required: true
type: string
mode:
description: Publication requires Phase 5D authorization and repository enablement
type: choice
options: [validate, publish]
default: validate
owner_authorization:
description: Leave empty for validation; explicit publication requires publish v1.0.0
type: string
default: ''
permissions:
contents: read
concurrency:
group: gem-github-release
cancel-in-progress: false
jobs:
validate:
if: github.repository == 'AlexMarinescu/pyGameMath' && github.ref == 'refs/heads/master' && github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
actions: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: gem-candidate-${{ inputs.validation_run_id }}
run-id: ${{ inputs.validation_run_id }}
github-token: ${{ github.token }}
path: ${{ runner.temp }}/gem-candidate
digest-mismatch: error
- name: Verify exact previously installed candidate assets without rebuilding
run: python tools/github_release.py --directory "${{ runner.temp }}/gem-candidate" --commit "$CANDIDATE_COMMIT" --run-id "$VALIDATION_RUN" --mode validate --output github-release-validation.json
env:
CANDIDATE_COMMIT: ${{ inputs.commit_sha }}
VALIDATION_RUN: ${{ inputs.validation_run_id }}
GITHUB_TOKEN: ${{ github.token }}
publish:
if: inputs.mode == 'publish' && vars.GEM_RELEASE_ENABLED == 'true' && inputs.owner_authorization == 'publish v1.0.0'
needs: validate
environment: gem-release-review
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
actions: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: gem-candidate-${{ inputs.validation_run_id }}
run-id: ${{ inputs.validation_run_id }}
github-token: ${{ github.token }}
path: ${{ runner.temp }}/gem-candidate
digest-mismatch: error
- name: Publish only after explicit owner authorization and protected approval
run: python tools/github_release.py --directory "${{ runner.temp }}/gem-candidate" --commit "$CANDIDATE_COMMIT" --run-id "$VALIDATION_RUN" --mode publish --output github-release-publication.json
env:
CANDIDATE_COMMIT: ${{ inputs.commit_sha }}
VALIDATION_RUN: ${{ inputs.validation_run_id }}
RELEASE_ENABLED: ${{ vars.GEM_RELEASE_ENABLED }}
OWNER_AUTHORIZATION: ${{ inputs.owner_authorization }}
GITHUB_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ github.token }}
61 changes: 46 additions & 15 deletions .github/workflows/package-validation.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,63 @@
name: Package validation
on:
pull_request:
push:
branches: [master]
workflow_dispatch:
workflow_call:
inputs:
source_ref:
description: Exact candidate SHA supplied by manual release preflight
type: string
default: ''
permissions:
contents: read
concurrency:
group: package-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
package:
runs-on: ubuntu-latest
name: ${{ matrix.os }} / Python ${{ matrix.python }}
runs-on: ${{ matrix.os }}
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python: ['3.10', '3.11', '3.12', '3.13', '3.14']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: actions/setup-python@v5
persist-credentials: false
ref: ${{ inputs.source_ref || github.sha }}
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python }}
- run: python -m pip install -r requirements-audit.txt -r requirements-build.txt six
- run: python -m pytest -q
- run: python tools/check_architecture_docs.py --examples --getting-started --api-reference --tutorials --showcase --website
- run: python -m build
- run: python -m twine check --strict dist/*
- run: python tools/verify_distribution.py --wheel dist/gem-1.0.0-py3-none-any.whl --sdist dist/gem-1.0.0.tar.gz
- run: python -m venv /tmp/gem-wheel && /tmp/gem-wheel/bin/python -m pip install dist/*.whl
- run: /tmp/gem-wheel/bin/python -I tools/verify_distribution.py --installed-root /tmp/gem-wheel/lib/python${{ matrix.python }}/site-packages
- run: python -m venv /tmp/gem-sdist && /tmp/gem-sdist/bin/python -m pip install dist/*.tar.gz
- run: /tmp/gem-sdist/bin/python -I tools/verify_distribution.py --installed-root /tmp/gem-sdist/lib/python${{ matrix.python }}/site-packages
- run: /tmp/gem-wheel/bin/python -I tools/check_architecture_docs.py --examples --getting-started --api-reference --tutorials --showcase --website --package-root /tmp/gem-wheel/lib/python${{ matrix.python }}/site-packages
- run: /tmp/gem-sdist/bin/python -I tools/check_architecture_docs.py --examples --getting-started --api-reference --tutorials --showcase --website --package-root /tmp/gem-sdist/lib/python${{ matrix.python }}/site-packages
- run: python -m pip install -r requirements-ci.txt
- name: Full suite, API examples, clean builds and isolated installs
run: python tools/ci_validate.py --output-dir "${{ runner.temp }}/gem-ci" --artifacts-dir dist
- name: Retain failure diagnostics and verification results
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: gem-checks-${{ runner.os }}-py${{ matrix.python }}-${{ github.run_id }}
path: |
${{ runner.temp }}/gem-ci/*.json
${{ runner.temp }}/gem-ci/*.xml
${{ runner.temp }}/gem-ci/*.log
if-no-files-found: warn
retention-days: 14
- name: Retain validated candidate (one canonical build)
if: success() && matrix.os == 'ubuntu-latest' && matrix.python == '3.12'
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: gem-candidate-${{ github.run_id }}
path: |
dist/gem-1.0.0-py3-none-any.whl
dist/gem-1.0.0.tar.gz
dist/candidate-manifest.json
dist/SHA256SUMS
dist/INSTALL.md
if-no-files-found: error
retention-days: 14
36 changes: 12 additions & 24 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,32 @@ on:
- 'README.md'
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '.github/workflows/documentation-artifact.yml'
- '.github/workflows/publish-docs.yml'
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: github-pages
cancel-in-progress: false

jobs:
build:
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install -r requirements-docs.txt
- run: python -m pip install -e .
- run: python -m mkdocs build --strict
- run: python tools/check_site.py --site-dir site
- run: python tools/check_architecture_docs.py --examples --getting-started --api-reference --tutorials --showcase --website
- uses: actions/upload-pages-artifact@v3
with:
path: site

if: github.repository == 'AlexMarinescu/pyGameMath' && github.ref == 'refs/heads/master'
uses: ./.github/workflows/documentation-artifact.yml
with:
pages_artifact: true
deploy:
needs: build
if: github.repository == 'AlexMarinescu/pyGameMath' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
101 changes: 101 additions & 0 deletions .github/workflows/release-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Manual release candidate validation
on:
workflow_dispatch:
inputs:
commit_sha:
description: Full lowercase SHA of the reviewed master commit
type: string
required: true
version:
description: Exact source distribution version
type: string
default: '1.0.0'
required: true
tag:
description: Proposed tag (this workflow never creates it)
type: string
default: 'v1.0.0'
required: true
mode:
description: Validation only, or protected human review; neither publishes
type: choice
options: [validate, review]
default: validate
permissions:
contents: read
concurrency:
group: gem-release-validation
cancel-in-progress: false
jobs:
preflight:
if: github.repository == 'AlexMarinescu/pyGameMath' && github.ref == 'refs/heads/master' && github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
actions: read
outputs:
commit: ${{ steps.gate.outputs.source_commit }}
tag: ${{ steps.gate.outputs.tag }}
mode: ${{ steps.gate.outputs.mode }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
- id: gate
run: python tools/release_gate.py preflight --output release-preflight.json
env:
INPUT_COMMIT: ${{ inputs.commit_sha }}
INPUT_VERSION: ${{ inputs.version }}
INPUT_TAG: ${{ inputs.tag }}
INPUT_MODE: ${{ inputs.mode }}
GITHUB_TOKEN: ${{ github.token }}
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-preflight-${{ github.run_id }}
path: release-preflight.json
if-no-files-found: error
validation:
needs: preflight
uses: ./.github/workflows/package-validation.yml
with:
source_ref: ${{ needs.preflight.outputs.commit }}
integrity:
needs: [preflight, validation]
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.preflight.outputs.commit }}
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.12'
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: gem-candidate-${{ github.run_id }}
path: ${{ runner.temp }}/gem-candidate
digest-mismatch: error
- run: python tools/release_gate.py verify-artifacts --directory "${{ runner.temp }}/gem-candidate" --commit "$CANDIDATE_COMMIT" --tag "$CANDIDATE_TAG" --output release-integrity.json
env:
CANDIDATE_COMMIT: ${{ needs.preflight.outputs.commit }}
CANDIDATE_TAG: ${{ needs.preflight.outputs.tag }}
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: release-integrity-${{ github.run_id }}
path: release-integrity.json
if-no-files-found: error
review:
if: needs.preflight.outputs.mode == 'review'
needs: [preflight, validation, integrity]
runs-on: ubuntu-latest
timeout-minutes: 5
environment: gem-release-review
steps:
- name: Record protected human review; publication remains disabled
run: echo "Candidate validation approved. PyPI authority remains unverified; no publication is enabled."
Loading
Loading