Bump version from 0.83.0 to 0.84.0 #626
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: ci | |
| on: | |
| pull_request: | |
| push: | |
| branches: [develop, main] | |
| tags: ["[0-9]+.[0-9]+.[0-9]+*"] | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: GitHub Actions deployment environment | |
| required: false | |
| type: environment | |
| env: | |
| DOCKER_BUILDKIT: "1" | |
| HATCH_ENV_TYPE_VIRTUAL_PATH: ".venv" | |
| HATCH_ENV: "ci" | |
| HATCH_VERSION: "1.15.1" | |
| PIPX_VERSION: "1.8.0" | |
| jobs: | |
| setup: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| environment-name: ${{ steps.set-env.outputs.environment-name }} | |
| environment-url: ${{ steps.set-env.outputs.environment-url }} | |
| repo-name: ${{ steps.set-env.outputs.repo-name }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set GitHub Actions deployment environment | |
| id: set-env | |
| run: | | |
| repo_name=${GITHUB_REPOSITORY##*/} | |
| if ${{ github.event_name == 'workflow_dispatch' }}; then | |
| environment_name=${{ inputs.environment }} | |
| elif ${{ github.ref_type == 'tag' }}; then | |
| environment_name="PyPI" | |
| else | |
| environment_name="" | |
| fi | |
| if [ "$environment_name" = "PyPI" ]; then | |
| url="https://pypi.org/project/$repo_name/" | |
| environment_url="$url$GITHUB_REF_NAME/" | |
| else | |
| timestamp="$(date -Iseconds)" | |
| url="https://api.github.com/repos/$GITHUB_REPOSITORY/deployments" | |
| environment_url="$url?timestamp=$timestamp" | |
| fi | |
| echo "environment-name=$environment_name" >>"$GITHUB_OUTPUT" | |
| echo "environment-url=$environment_url" >>"$GITHUB_OUTPUT" | |
| echo "repo-name=$repo_name" >>"$GITHUB_OUTPUT" | |
| - name: Create annotation for deployment environment | |
| if: steps.set-env.outputs.environment-name != '' | |
| run: echo "::notice::Deployment environment ${{ steps.set-env.outputs.environment-name }}" | |
| python: | |
| runs-on: ubuntu-latest | |
| needs: [setup] | |
| strategy: | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12", "3.13"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Set up pip cache | |
| if: runner.os == 'Linux' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} | |
| restore-keys: ${{ runner.os }}-pip- | |
| - name: Install pipx for Python ${{ matrix.python-version }} | |
| run: python -m pip install "pipx==$PIPX_VERSION" | |
| - name: Install Hatch | |
| run: pipx install "hatch==$HATCH_VERSION" | |
| - name: Test Hatch version | |
| run: | | |
| HATCH_VERSION_INSTALLED=$(hatch --version) | |
| echo "The HATCH_VERSION environment variable is set to $HATCH_VERSION." | |
| echo "The installed Hatch version is ${HATCH_VERSION_INSTALLED##Hatch, version }." | |
| case $HATCH_VERSION_INSTALLED in | |
| *$HATCH_VERSION) echo "Hatch version correct." ;; | |
| *) echo "Hatch version incorrect." && exit 1 ;; | |
| esac | |
| - name: Install dependencies | |
| run: hatch env create ${{ env.HATCH_ENV }} | |
| - name: Test virtualenv location | |
| run: | | |
| EXPECTED_VIRTUALENV_PATH="$GITHUB_WORKSPACE/$HATCH_ENV_TYPE_VIRTUAL_PATH" | |
| INSTALLED_VIRTUALENV_PATH=$(hatch env find) | |
| echo "The virtualenv should be at $EXPECTED_VIRTUALENV_PATH." | |
| echo "Hatch is using a virtualenv at $INSTALLED_VIRTUALENV_PATH." | |
| case "$INSTALLED_VIRTUALENV_PATH" in | |
| "$EXPECTED_VIRTUALENV_PATH") echo "Correct Hatch virtualenv." ;; | |
| *) echo "Incorrect Hatch virtualenv." && exit 1 ;; | |
| esac | |
| - name: Test that Git tag version and Python package version match | |
| if: github.ref_type == 'tag' && matrix.python-version == '3.13' | |
| run: | | |
| GIT_TAG_VERSION=$GITHUB_REF_NAME | |
| PACKAGE_VERSION=$(hatch version) | |
| echo "The Python package version is $PACKAGE_VERSION." | |
| echo "The Git tag version is $GIT_TAG_VERSION." | |
| if [ "$PACKAGE_VERSION" = "$GIT_TAG_VERSION" ]; then | |
| echo "Versions match." | |
| else | |
| echo "Versions do not match." && exit 1 | |
| fi | |
| - name: Run Hatch script for code quality checks | |
| run: hatch run ${{ env.HATCH_ENV }}:check | |
| - name: Run tests | |
| run: | | |
| hatch run ${{ env.HATCH_ENV }}:coverage run | |
| coverage_files_after_run=$(find . -name '.coverage*' | wc -l) | |
| sleep_time=10 | |
| sleep "$sleep_time" | |
| coverage_files_after_sleep=$(find . -name '.coverage*' | wc -l) | |
| echo "[INFO] Verifying that coverage.py has stopped generating .coverage files. | |
| [INFO] Number of coverage files after coverage run: $coverage_files_after_run | |
| [INFO] Number of coverage files after $sleep_time second sleep: $coverage_files_after_sleep | |
| " | |
| if [ "$coverage_files_after_sleep" -gt "$coverage_files_after_run" ]; then | |
| echo "[ERROR] Unexpected .coverage files detected." | |
| exit 1 | |
| fi | |
| timeout-minutes: 5 | |
| - name: Enforce test coverage | |
| run: | | |
| hatch run ${{ env.HATCH_ENV }}:coverage combine -q | |
| hatch run ${{ env.HATCH_ENV }}:coverage report | |
| - name: Build Python package | |
| run: hatch build | |
| - name: Upload Python package artifacts | |
| if: > | |
| github.ref_type == 'tag' && | |
| matrix.python-version == '3.13' && | |
| needs.setup.outputs.environment-name == 'PyPI' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| if-no-files-found: error | |
| name: ${{ needs.setup.outputs.repo-name }}-${{ github.ref_name }} | |
| path: dist | |
| docker: | |
| runs-on: ubuntu-latest | |
| needs: [setup, python] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| linux-version: ["alpine", "trixie", "slim-trixie"] | |
| python-version: ["3.10", "3.11", "3.12", "3.13"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - run: python3 -m pip install 'httpie>=3,<4' 'urllib3>=1,<2' | |
| - name: Set up versions and Docker tags for Python and Alpine Linux | |
| id: setup | |
| run: | | |
| LINUX_VERSION=${{ matrix.linux-version }} | |
| linux_version_without_debian_release_name="${LINUX_VERSION/trixie/}" | |
| linux_tag="${linux_version_without_debian_release_name%-}" | |
| LINUX_TAG="${linux_tag:+-$linux_tag}" | |
| PYTHON_VERSION=${{ matrix.python-version }} | |
| PYTHON_TAG="-python$PYTHON_VERSION" | |
| echo "LINUX_VERSION=$LINUX_VERSION" >> $GITHUB_ENV | |
| echo "LINUX_TAG=$LINUX_TAG" >> $GITHUB_ENV | |
| echo "PYTHON_VERSION=$PYTHON_VERSION" >> $GITHUB_ENV | |
| echo "PYTHON_TAG=$PYTHON_TAG" >> $GITHUB_ENV | |
| - name: Build Docker images | |
| run: | | |
| docker build . --rm --target base \ | |
| --build-arg BUILDKIT_INLINE_CACHE=1 \ | |
| --build-arg HATCH_VERSION="$HATCH_VERSION" \ | |
| --build-arg LINUX_VERSION="$LINUX_VERSION" \ | |
| --build-arg PIPX_VERSION="$PIPX_VERSION" \ | |
| --build-arg PYTHON_VERSION="$PYTHON_VERSION" \ | |
| --cache-from ghcr.io/br3ndonland/inboard \ | |
| -t ghcr.io/br3ndonland/inboard:base"$LINUX_TAG" | |
| docker build . --rm --target starlette \ | |
| --build-arg BUILDKIT_INLINE_CACHE=1 \ | |
| --build-arg HATCH_VERSION="$HATCH_VERSION" \ | |
| --build-arg LINUX_VERSION="$LINUX_VERSION" \ | |
| --build-arg PIPX_VERSION="$PIPX_VERSION" \ | |
| --build-arg PYTHON_VERSION="$PYTHON_VERSION" \ | |
| -t ghcr.io/br3ndonland/inboard:starlette"$LINUX_TAG" | |
| docker build . --rm --target fastapi \ | |
| --build-arg BUILDKIT_INLINE_CACHE=1 \ | |
| --build-arg HATCH_VERSION="$HATCH_VERSION" \ | |
| --build-arg LINUX_VERSION="$LINUX_VERSION" \ | |
| --build-arg PIPX_VERSION="$PIPX_VERSION" \ | |
| --build-arg PYTHON_VERSION="$PYTHON_VERSION" \ | |
| -t ghcr.io/br3ndonland/inboard:fastapi"$LINUX_TAG" | |
| - name: Run Docker containers for testing | |
| run: | | |
| docker run -d -p 80:80 --name inboard-base \ | |
| -e "BASIC_AUTH_USERNAME=test_user" \ | |
| -e "BASIC_AUTH_PASSWORD=r4ndom_bUt_memorable" \ | |
| ghcr.io/br3ndonland/inboard:base"$LINUX_TAG" | |
| docker run -d -p 81:80 --name inboard-starlette \ | |
| -e "BASIC_AUTH_USERNAME=test_user" \ | |
| -e "BASIC_AUTH_PASSWORD=r4ndom_bUt_memorable" \ | |
| ghcr.io/br3ndonland/inboard:starlette"$LINUX_TAG" | |
| docker run -d -p 82:80 --name inboard-fastapi \ | |
| -e "BASIC_AUTH_USERNAME=test_user" \ | |
| -e "BASIC_AUTH_PASSWORD=r4ndom_bUt_memorable" \ | |
| ghcr.io/br3ndonland/inboard:fastapi"$LINUX_TAG" | |
| - name: Test Hatch version in Docker containers | |
| run: | | |
| test_hatch_version_in_docker() { | |
| echo "The HATCH_VERSION environment variable is set to $HATCH_VERSION." | |
| local hatch_version_in_docker hatch_version_in_docker_full | |
| for container_name in "$@"; do | |
| hatch_version_in_docker_full=$(docker exec "$container_name" hatch --version) | |
| hatch_version_in_docker="${hatch_version_in_docker_full##Hatch, version }" | |
| if [ -n "$hatch_version_in_docker" ]; then | |
| echo "Docker container $container_name has $hatch_version_in_docker." | |
| fi | |
| case $hatch_version_in_docker in | |
| *$HATCH_VERSION) echo "Hatch versions match for $container_name." ;; | |
| *) echo "Hatch version test failed for $container_name." && return 1 ;; | |
| esac | |
| done | |
| } | |
| test_hatch_version_in_docker inboard-base inboard-starlette inboard-fastapi | |
| - name: Test virtualenv location in Docker containers | |
| run: | | |
| test_virtualenv_location_in_docker() { | |
| local docker_virtualenv docker_python expected_virtualenv expected_python | |
| expected_virtualenv="/app/$HATCH_ENV_TYPE_VIRTUAL_PATH" | |
| expected_python="$expected_virtualenv/bin/python" | |
| echo "The Hatch virtualenv should be at $expected_virtualenv." | |
| echo "The Python executable should be at $expected_python." | |
| for container_name in "$@"; do | |
| docker_virtualenv=$(docker exec "$container_name" hatch env find) | |
| docker_python=$(docker exec "$container_name" which python) | |
| case "$docker_virtualenv" in | |
| "$expected_virtualenv") echo "Correct Hatch virtualenv $docker_virtualenv for $container_name." ;; | |
| *) echo "Incorrect Hatch virtualenv $docker_virtualenv for $container_name." && return 1 ;; | |
| esac | |
| case "$docker_python" in | |
| "$expected_python") echo "Correct Python $docker_python for $container_name." ;; | |
| *) echo "Incorrect Python $docker_python for $container_name." && return 1 ;; | |
| esac | |
| done | |
| } | |
| test_virtualenv_location_in_docker inboard-base inboard-starlette inboard-fastapi | |
| - name: Smoke test Docker containers | |
| run: | | |
| handle_error_code() { | |
| case "$1" in | |
| 2) : 'Request timed out!' ;; | |
| 3) : 'Unexpected HTTP 3xx Redirection!' ;; | |
| 4) : 'HTTP 4xx Client Error!' ;; | |
| 5) : 'HTTP 5xx Server Error!' ;; | |
| 6) : 'Exceeded --max-redirects=<n> redirects!' ;; | |
| *) : 'Other Error!' ;; | |
| esac | |
| echo "$_" | |
| return "$1" | |
| } | |
| smoke_test() { | |
| if http --check-status --ignore-stdin -q --timeout=5 "$@"; then | |
| echo 'Smoke test passed. OK!' | |
| else | |
| handle_error_code "$?" | |
| fi | |
| } | |
| smoke_test_xfail() { | |
| if http --check-status --ignore-stdin -q --timeout=5 "$@" &>/dev/null; then | |
| echo 'Smoke test should have failed!' | |
| return 1 | |
| else | |
| echo 'Smoke test expected to fail. OK!' | |
| fi | |
| } | |
| smoke_test :80 | |
| smoke_test :81 | |
| smoke_test :82 | |
| smoke_test -a test_user:r4ndom_bUt_memorable :81/status | |
| smoke_test -a test_user:r4ndom_bUt_memorable :82/status | |
| smoke_test_xfail -a test_user:incorrect_password :81/status | |
| smoke_test_xfail -a test_user:incorrect_password :82/status | |
| smoke_test_xfail :81/status | |
| smoke_test_xfail :82/status | |
| - name: Log in to Docker registry | |
| if: > | |
| github.ref_type == 'tag' || | |
| github.ref == 'refs/heads/develop' || | |
| github.ref == 'refs/heads/main' | |
| run: | | |
| echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io \ | |
| -u ${{ github.actor }} --password-stdin | |
| - name: Tag and push Docker images with latest tags | |
| if: > | |
| matrix.python-version == '3.13' && | |
| ( | |
| github.ref_type == 'tag' || | |
| github.ref == 'refs/heads/develop' || | |
| github.ref == 'refs/heads/main' | |
| ) | |
| run: | | |
| docker push ghcr.io/br3ndonland/inboard:base"$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:starlette"$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:fastapi"$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:fastapi"$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:latest"$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:latest"$LINUX_TAG" | |
| - name: Tag and push Docker images with Python version | |
| if: github.ref_type == 'tag' || github.ref == 'refs/heads/main' | |
| run: | | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:base"$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:base"$PYTHON_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:starlette"$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:starlette"$PYTHON_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:fastapi"$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:fastapi"$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:base"$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:starlette"$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:fastapi"$PYTHON_TAG$LINUX_TAG" | |
| - name: Tag and push Docker images with Git tag | |
| if: github.ref_type == 'tag' | |
| run: | | |
| GIT_TAG_FULL=${{ github.ref_name }} | |
| GIT_TAG_MAJOR_MINOR=$(echo "$GIT_TAG_FULL" | cut -d '.' -f 1-2) | |
| for GIT_TAG in "$GIT_TAG_FULL" "$GIT_TAG_MAJOR_MINOR"; do | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"base$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"base-$GIT_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"starlette$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"starlette-$GIT_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"fastapi$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"fastapi-$GIT_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"base$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"base-$GIT_TAG$PYTHON_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"starlette$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"starlette-$GIT_TAG$PYTHON_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"fastapi$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"fastapi-$GIT_TAG$PYTHON_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"base$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"$GIT_TAG-base$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"starlette$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"$GIT_TAG-starlette$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"fastapi$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"$GIT_TAG-fastapi$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"base$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"$GIT_TAG-base$PYTHON_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"starlette$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"$GIT_TAG-starlette$PYTHON_TAG$LINUX_TAG" | |
| docker tag \ | |
| ghcr.io/br3ndonland/inboard:"fastapi$LINUX_TAG" \ | |
| ghcr.io/br3ndonland/inboard:"$GIT_TAG-fastapi$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"base-$GIT_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"starlette-$GIT_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"fastapi-$GIT_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"base-$GIT_TAG$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"starlette-$GIT_TAG$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"fastapi-$GIT_TAG$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"$GIT_TAG-base$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"$GIT_TAG-starlette$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"$GIT_TAG-fastapi$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"$GIT_TAG-base$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"$GIT_TAG-starlette$PYTHON_TAG$LINUX_TAG" | |
| docker push ghcr.io/br3ndonland/inboard:"$GIT_TAG-fastapi$PYTHON_TAG$LINUX_TAG" | |
| done | |
| pypi: | |
| environment: | |
| name: ${{ needs.setup.outputs.environment-name }} | |
| url: ${{ needs.setup.outputs.environment-url }} | |
| if: github.ref_type == 'tag' && needs.setup.outputs.environment-name == 'PyPI' | |
| needs: [setup, python, docker] | |
| permissions: | |
| id-token: write | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download Python package artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| merge-multiple: true | |
| name: ${{ needs.setup.outputs.repo-name }}-${{ github.ref_name }} | |
| path: dist | |
| - name: Publish Python package to PyPI | |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 | |
| changelog: | |
| if: github.ref_type == 'tag' | |
| needs: [setup, python, docker, pypi] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: develop | |
| - name: Generate changelog from Git tags | |
| run: | | |
| # Generate changelog from Git tags | |
| echo '# Changelog | |
| ' >CHANGELOG.md | |
| # shellcheck disable=SC2016 | |
| echo '# Changelog | |
| [View on GitHub](https://github.com/${{github.repository}}/blob/HEAD/CHANGELOG.md) | |
| ' >docs/changelog.md | |
| GIT_LOG_FORMAT='## %(subject) - %(taggerdate:short) | |
| %(contents:body) | |
| Tagger: %(taggername) %(taggeremail) | |
| Date: %(taggerdate:iso) | |
| ```text | |
| %(contents:signature)``` | |
| ' | |
| git tag -l --sort=-taggerdate:iso --format="$GIT_LOG_FORMAT" >>CHANGELOG.md | |
| git tag -l --sort=-taggerdate:iso --format="$GIT_LOG_FORMAT" >>docs/changelog.md | |
| - name: Fix changelog | |
| run: | | |
| # Fix changelog | |
| # | |
| # The previous step in the GitHub Actions job generates a changelog | |
| # from Git tag messages and writes the output to Markdown documents. | |
| # https://github.com/br3ndonland/inboard/commit/b15efff7fc45759983743411fcbbd52415eb5455 | |
| # | |
| # Some post-processing of these Git tag messages may be necessary in order | |
| # for them to render properly from the Markdown documents. One reason for | |
| # this post-processing is to handle "dunders" (double underscores). | |
| # | |
| # Dunder names like `__init__` have special meaning in Python. | |
| # https://docs.python.org/3/reference/datamodel.html#specialnames | |
| # https://docs.python.org/3/reference/lexical_analysis.html | |
| # | |
| # Dunders also make text bold in Markdown unless escaped with backslashes | |
| # or enclosed in backticks. When the document is transformed to HTML, the | |
| # backticks are transformed to HTML code elements. | |
| # | |
| # Some early changelog entries in this project did not enclose dunders in | |
| # backticks. When the text from these entries is formatted as Markdown and | |
| # rendered, text within dunders like `__init__` shows up as "init" in bold | |
| # because Markdown parsers read it as equivalent to `**init**`. To avoid | |
| # having these dunder names converted to bold text, the GitHub Actions job | |
| # runs a `sed` command to escape the dunders, like \_\_init\_\_. | |
| # | |
| # The changelog entry for the update to Gunicorn 23.0.0 mentions a | |
| # security vulnerability that was fixed, but this vulnerability was | |
| # actually fixed in Gunicorn 22.0.0 and described in the changelog | |
| # for inboard 0.68.0. This step removes the duplicate info. | |
| # https://github.com/br3ndonland/inboard/pull/117 | |
| ESCAPE_DUNDERS='s:(\s|\/)(__)(all|init|token)(__)(\s|\.py|\(\)){0,1}:\1\\_\\_\3\\_\\_\5:g' | |
| REPLACEMENT='There are several breaking changes noted in the\n[Gunicorn changelog](https://docs.gunicorn.org/en/latest/news.html).' | |
| for changelog in "CHANGELOG.md" "docs/changelog.md"; do | |
| sed -Ei "$ESCAPE_DUNDERS" "$changelog" | |
| sed -Ei \ | |
| -e "s|\[Changes\]\(https://docs.gunicorn.org/en/latest/news.html\) include|$REPLACEMENT|g" \ | |
| -e "s|a fix for a high-severity security vulnerability \(CVE-2024-1135,||g" \ | |
| -e "s|\[GHSA-w3h3-4rj7-4ph4\]\(https://github.com/advisories/GHSA-w3h3-4rj7-4ph4\)\)\.||g" \ | |
| -e "s|There are several breaking changes noted in the Gunicorn changelog\.||g" \ | |
| "$changelog" | |
| sed -Ei -z "s|\n\n\n||g" "$changelog" | |
| done | |
| - name: Format changelog with Prettier | |
| run: npx -s -y prettier@'^3' --write CHANGELOG.md docs/changelog.md | |
| - name: Create pull request with updated changelog | |
| uses: peter-evans/create-pull-request@v7 | |
| with: | |
| add-paths: | | |
| CHANGELOG.md | |
| docs/changelog.md | |
| branch: create-pull-request/${{ github.ref_name }} | |
| commit-message: Update changelog for version ${{ github.ref_name }} | |
| sign-commits: true | |
| title: Update changelog for version ${{ github.ref_name }} |