diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 25ecb0dca..989a3a05a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -21,7 +21,7 @@ on: - cron: '44 21 * * 0' jobs: - analyze: + run: name: Analyze # Runner size impacts CodeQL analysis time. To learn more, please see: # - https://gh.io/recommended-hardware-resources-for-running-codeql @@ -43,11 +43,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4.1.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: config-file: ./.github/codeql/config.yml languages: ${{ matrix.language }} @@ -59,6 +59,6 @@ jobs: # queries: security-extended,security-and-quality - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2c5f95d27..35613bd45 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -15,16 +15,16 @@ jobs: steps: - name: Acquire sources - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v4.1.1 - name: Setup Python - uses: actions/setup-python@v4.3.0 + uses: actions/setup-python@v5.0.0 with: python-version: "3.12" architecture: x64 - name: Apply caching of dependencies - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.3.2 with: path: ~/.cache/pip key: pip-${{ hashFiles('**/requirements-*.txt') }} diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index ba46648a5..6a0196d0c 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -14,16 +14,16 @@ jobs: steps: - name: Acquire sources - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v4.1.1 - name: Setup Python - uses: actions/setup-python@v4.3.0 + uses: actions/setup-python@v5.0.0 with: - python-version: 3.11 + python-version: "3.12" architecture: x64 - name: Apply caching of dependencies - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.3.2 with: path: ~/.cache/pip key: pip-${{ hashFiles('**/requirements-*.txt') }} diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 616d70c87..68d51d2a5 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -15,16 +15,16 @@ jobs: steps: - name: Acquire sources - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v4.1.1 - name: Setup Python - uses: actions/setup-python@v4.3.0 + uses: actions/setup-python@v5.0.0 with: - python-version: "3.11" + python-version: "3.12" architecture: x64 - name: Apply caching of dependencies - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.3.2 with: path: ~/.cache/pip key: pip-${{ hashFiles('**/requirements-*.txt') }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 25838d08e..62c555c74 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,7 +6,7 @@ on: jobs: - tests: + run: runs-on: ${{ matrix.os }} strategy: @@ -25,16 +25,16 @@ jobs: steps: - name: Acquire sources - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v4.1.1 - name: Setup Python - uses: actions/setup-python@v4.3.0 + uses: actions/setup-python@v5.0.0 with: python-version: ${{ matrix.python-version }} architecture: x64 - name: Apply caching of dependencies - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.3.2 with: path: ~/.cache/pip key: os=${{ matrix.os }}-python=${{ matrix.python-version }}-pip-${{ hashFiles('**/requirements-*.txt') }} @@ -42,10 +42,7 @@ jobs: - name: Install dependencies run: | pip install -U pip setuptools wheel - pip install -r requirements.txt -r requirements/requirements-test.txt -r requirements/requirements-docs.txt django~=${{ matrix.django-version }} cryptography~=${{ matrix.cryptography-version }} - - - name: Install program - run: pip install -e . + pip install -r requirements.txt -r requirements/requirements-test.txt django~=${{ matrix.django-version }} cryptography~=${{ matrix.cryptography-version }} - name: Initialize demo run: python dev.py init-demo diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 38361dab3..8c7dd7c1a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -7,7 +7,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.10" + python: "3.12" jobs: pre_build: - make -C docs extra-files diff --git a/devscripts/config.py b/devscripts/config.py index 17b3201d0..dd983f663 100644 --- a/devscripts/config.py +++ b/devscripts/config.py @@ -49,7 +49,8 @@ def minor_to_major(version: str) -> str: with open(PYPROJECT_PATH, "rb") as _pyproject_stream: - _release_config = tomllib.load(_pyproject_stream)["django-ca"]["release"] + _pyproject_toml = tomllib.load(_pyproject_stream) +_release_config = _pyproject_toml["django-ca"]["release"] PYTHON_RELEASES = tuple(typing.cast(List[str], _release_config["python"])) DJANGO = tuple(typing.cast(List[str], _release_config["django"])) @@ -59,6 +60,7 @@ def minor_to_major(version: str) -> str: ALPINE_RELEASES = tuple(typing.cast(List[str], _release_config["alpine"])) DEBIAN_RELEASES = tuple(typing.cast(List[str], _release_config["debian-releases"])) UBUNTU_RELEASES = tuple(typing.cast(List[str], _release_config["ubuntu-releases"])) +GITHUB_CONFIG = _release_config["github"] # Compute list of valid alpine images _alpine_images = ["default"] diff --git a/devscripts/validation/state.py b/devscripts/validation/state.py index 63efe6f82..223f7d2fc 100644 --- a/devscripts/validation/state.py +++ b/devscripts/validation/state.py @@ -100,17 +100,48 @@ def check( return errors +def check_github_action_versions(job) -> int: + """Check versions of/in GitHub actions.""" + errors = 0 + expected_action_versions = config.GITHUB_CONFIG["actions"] + for step_config in job["steps"]: + if step_uses := step_config.get("uses"): + action, action_version = step_uses.split("@", 1) + + if expected_action_version := expected_action_versions.get(action): + if expected_action_version != action_version: + errors += err(f"{action}: Have {action_version}, expected {expected_action_version}") + else: + info(f"{action}: action version not configured") + + if action == "actions/setup-python": + py_version = step_config["with"]["python-version"] + if py_version != "${{ matrix.python-version }}" and py_version != config.PYTHON_RELEASES[-1]: + errors += err(f"Outdated Python version: {py_version}") + return errors + + def check_github_actions_tests() -> int: """Check GitHub actions.""" - relpath = Path(".github", "workflows", "tests.yml") - check_path(relpath) - with open(config.ROOT_DIR / relpath, encoding="utf-8") as stream: - action_config = yaml.safe_load(stream) - matrix = action_config["jobs"]["tests"]["strategy"]["matrix"] - - errors = simple_diff("Python versions", tuple(matrix["python-version"]), config.PYTHON_RELEASES) - errors += simple_diff("Django versions", tuple(matrix["django-version"]), config.DJANGO) - errors += simple_diff("cryptography versions", tuple(matrix["cryptography-version"]), config.CRYPTOGRAPHY) + errors = 0 + for workflow in Path(".github", "workflows").glob("*.yml"): + check_path(workflow) + with open(config.ROOT_DIR / workflow, encoding="utf-8") as stream: + action_config = yaml.safe_load(stream) + + for job_name, job in action_config["jobs"].items(): + check_github_action_versions(job) + + if workflow.name == "tests.yml": + matrix = job["strategy"]["matrix"] + errors += simple_diff( + "Python versions", tuple(matrix["python-version"]), config.PYTHON_RELEASES + ) + errors += simple_diff("Django versions", tuple(matrix["django-version"]), config.DJANGO) + errors += simple_diff( + "cryptography versions", tuple(matrix["cryptography-version"]), config.CRYPTOGRAPHY + ) + return errors diff --git a/pyproject.toml b/pyproject.toml index a78f61d6d..4e67e94d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,17 @@ ubuntu-releases = [ "mantic", # 23.10, until 2024-07 ] +[django-ca.release.github] +# Action versions can be retrieved directly from the GitHub "marketplace", e.g.: +# https://github.com/marketplace/actions/checkout +actions."actions/checkout" = "v4.1.1" +actions."actions/setup-python" = "v5.0.0" +actions."actions/cache" = "v3.3.2" +# CodeQL actions are actually all in the same repository: +# https://github.com/github/codeql-action +actions."github/codeql-action/init" = "v3" +actions."github/codeql-action/analyze" = "v3" + [django-ca.validation] # list glob-style patterns to exclude from any check (currently only license headers) excludes = [