-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: doc-deploy-changelog action (#452)
Co-authored-by: Roberto Pastor Muela <37798125+RobPasMue@users.noreply.github.com>
- Loading branch information
Showing
6 changed files
with
380 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,301 @@ | ||
# Copyright (C) 2022 - 2024 ANSYS, Inc. and/or its affiliates. | ||
# SPDX-License-Identifier: MIT | ||
# | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in all | ||
# copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
# SOFTWARE. | ||
|
||
name: > | ||
Build CHANGELOG from towncrier fragment files | ||
description: | | ||
Builds the CHANGELOG using ``towncrier`` fragment files for the tagged version. | ||
Creates a pull request into main with the CHANGELOG updates and deleted | ||
towncrier fragment files. | ||
This action will only work on Linux/macOS runners. | ||
inputs: | ||
# Required inputs | ||
|
||
token: | ||
description: > | ||
Use the PYANSYS_CI_BOT_TOKEN to do a git commit & push. | ||
The "contents: write" and "pull-requests: write" permissions | ||
are required for this action. | ||
required: true | ||
type: string | ||
|
||
# Optional inputs | ||
|
||
python-version: | ||
description: > | ||
Python version used for setting up Python. | ||
default: '3.10' | ||
required: false | ||
type: string | ||
|
||
towncrier-version: | ||
description: > | ||
Towncrier version used for updating the CHANGELOG file. | ||
default: '23.11.0' | ||
required: false | ||
type: string | ||
|
||
toml-version: | ||
description: > | ||
Toml version used for retrieving the towncrier directory. | ||
default: '0.10.2' | ||
required: false | ||
type: string | ||
|
||
use-python-cache: | ||
description: > | ||
Whether to use the Python cache for installing previously downloaded | ||
libraries. If ``true``, previously downloaded libraries are installed from the | ||
Python cache. If ``false``, libraries are downloaded from the PyPI index. | ||
required: false | ||
default: true | ||
type: boolean | ||
|
||
update-release-branch: | ||
description: > | ||
Whether or not to update the CHANGELOG in the release branch. | ||
If ``true``, the branch used to update the CHANGELOG is "release/major.minor". | ||
If ``false``, the branch used to update the CHANGELOG is | ||
"maint/changelog-update-tag_version" and will be deleted after use. | ||
required: false | ||
default: true | ||
type: boolean | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: "Install Git and clone project" | ||
uses: actions/checkout@v4 | ||
with: | ||
token: ${{ inputs.token }} | ||
fetch-depth: 0 | ||
|
||
- name: "Set up Python ${{ inputs.python-version }}" | ||
env: | ||
PYTHON_VERSION: ${{ inputs.python-version }} | ||
PYTHON_CACHE: ${{ inputs.use-python-cache }} | ||
uses: ansys/actions/_setup-python@main | ||
with: | ||
python-version: ${{ env.PYTHON_VERSION }} | ||
use-cache: ${{ env.PYTHON_CACHE }} | ||
|
||
- name: Save tag version | ||
shell: bash | ||
run: | | ||
# /refs/tags/v0.1.0 -> 0.1.0 | ||
echo "TAG_VERSION=${GITHUB_REF##*/v}" >> $GITHUB_ENV | ||
- name: "Install towncrier, toml, and the project" | ||
shell: bash | ||
run: | | ||
python -m pip install --upgrade pip towncrier==${{ inputs.towncrier-version }} toml==${{ inputs.toml-version }} | ||
python -m pip install -e . | ||
- name: "Get towncrier directory" | ||
shell: python | ||
run: | | ||
import os | ||
import toml | ||
# Load pyproject.toml | ||
with open('pyproject.toml', 'r') as f: | ||
config = toml.load(f) | ||
directory=config["tool"]["towncrier"]["directory"] | ||
# Get the GITHUB_ENV variable | ||
github_env = os.getenv('GITHUB_ENV') | ||
# Append the TOWNCRIER_DIR with its value to GITHUB_ENV | ||
with open(github_env, "a") as f: | ||
f.write(f"TOWNCRIER_DIR={directory}") | ||
- name: "Set CHANGELOG update branch" | ||
shell: bash | ||
run: | | ||
if [[ ${{ inputs.update-release-branch }} == "true" ]]; then | ||
# Assume release branch is "release/major.minor" | ||
# v0.1.0 (tag) -> release/0.1 | ||
tag_version=${{ env.TAG_VERSION }} | ||
release_branch="release/${tag_version%.*}" | ||
# Check release_branch exists on remote | ||
release_branch_exists=$(git ls-remote --heads origin refs/heads/$release_branch 2>&1) | ||
# If the release branch doesn't exist, then use the temporary branch | ||
if [ -z "$release_branch_exists" ]; then | ||
# maint/changelog-update-v0.1.0 | ||
echo "UPDATE_BRANCH=maint/changelog-update-v${{ env.TAG_VERSION }}" >> $GITHUB_ENV | ||
echo "RELEASE_BRANCH_EXISTS=false" >> $GITHUB_ENV | ||
else | ||
echo "UPDATE_BRANCH=$release_branch" >> $GITHUB_ENV | ||
echo "RELEASE_BRANCH_EXISTS=true" >> $GITHUB_ENV | ||
fi | ||
else | ||
# maint/changelog-update-v0.1.0 | ||
echo "UPDATE_BRANCH=maint/changelog-update-v${{ env.TAG_VERSION }}" >> $GITHUB_ENV | ||
echo "RELEASE_BRANCH_EXISTS=false" >> $GITHUB_ENV | ||
fi | ||
- name: "Create new section in CHANGELOG and reupload tag" | ||
shell: bash | ||
run: | | ||
# Get number of .md files in ${{ env.TOWNCRIER_DIR }} | ||
count=$(find ${{ env.TOWNCRIER_DIR }} -type f -name "*.md" | wc -l) | ||
if [ $count -gt 0 ]; then | ||
# Checkout branch from tag | ||
if [[ ${{ inputs.update-release-branch }} == "true" ]] && [[ ${{ env.RELEASE_BRANCH_EXISTS }} == "true" ]]; then | ||
echo "Using release branch" | ||
git checkout ${{ env.UPDATE_BRANCH }} | ||
git pull | ||
else | ||
echo "Using temporary branch" | ||
git checkout -b ${{ env.UPDATE_BRANCH }} | ||
fi | ||
# Update the changelog with the package version from pyproject.toml | ||
# The [tool.towncrier] section in pyproject.toml requires the following line | ||
# for the command to work: | ||
# package = "ansys.<product>.<library>" | ||
buildcmd=$(towncrier build --yes >> builderr.txt 2>&1 || true) | ||
cat builderr.txt | ||
greperr=$(grep "Error: '--version'" builderr.txt || true) | ||
# Remove builderr.txt | ||
rm builderr.txt | ||
# If greperr contains the error message, run with the tag specified | ||
if [ -n "$greperr" ]; then | ||
# Update changelog with the tag version | ||
towncrier build --yes --version ${{ env.TAG_VERSION }} | ||
fi | ||
# Configure git username & email | ||
git config user.name 'pyansys-ci-bot' | ||
git config user.email 'pyansys.github.bot@ansys.com' | ||
# Add CHANGELOG.md file and deleted ${{ env.TOWNCRIER_DIR }}/*.md files | ||
git add . | ||
# Commit changes and save commit SHA | ||
git commit -m "Updating CHANGELOG for v${{ env.TAG_VERSION }}" | ||
echo "COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV | ||
# Push CHANGELOG.md changes | ||
if [[ ${{ inputs.update-release-branch }} == "true" ]] && [[ ${{ env.RELEASE_BRANCH_EXISTS }} == "true" ]]; then | ||
git push | ||
else | ||
git push -u origin ${{ env.UPDATE_BRANCH }} | ||
fi | ||
echo "UPDATED_CHANGELOG=True" >> $GITHUB_ENV | ||
else | ||
echo "There are no changelog fragment files to update the CHANGELOG for v${{ env.TAG_VERSION }}" | ||
echo "UPDATED_CHANGELOG=False" >> $GITHUB_ENV | ||
fi | ||
- name: "Create PR into main with CHANGELOG changes" | ||
if: contains(env.UPDATED_CHANGELOG, 'True') | ||
env: | ||
GH_TOKEN: ${{ inputs.token }} | ||
shell: bash | ||
run: | | ||
# Get main branch name | ||
head_branch=$(git remote show origin | grep "HEAD branch:") | ||
formatted_head_branch=${head_branch#*: } | ||
# Checkout main & create a branch | ||
git checkout $formatted_head_branch | ||
git pull | ||
# Set branch for PR | ||
pr_branch=maint/v${{ env.TAG_VERSION }}-changelog | ||
# Check if pr_branch exists on remote | ||
remote_branch_exists=$(git ls-remote --heads origin refs/heads/$pr_branch 2>&1) | ||
# Delete the remote branch if it exists | ||
if [ -n "$remote_branch_exists" ]; then | ||
echo "Deleting $pr_branch from remote" | ||
git push origin --delete $pr_branch | ||
fi | ||
# Create a new $pr_branch | ||
git checkout -b $pr_branch | ||
cherrypick=$(git cherry-pick ${{ env.COMMIT_SHA }} >> cherrypickerr.txt 2>&1 || true) | ||
cat cherrypickerr.txt | ||
conflict=$(grep "CONFLICT" cherrypickerr.txt || true) | ||
# Remove cherrypickerr.txt | ||
rm cherrypickerr.txt | ||
if [ -n "$conflict" ]; then | ||
# Show which files are "theirs" from the cherry-pick | ||
git status | ||
# Apply all of the changes from the cherry-pick | ||
git checkout --theirs . | ||
git add . | ||
# Continue the cherry-pick without a commit message | ||
git -c core.editor=true cherry-pick --continue | ||
fi | ||
# Push CHANGELOG.md changes to $pr_branch | ||
git push -u origin $pr_branch | ||
gh pr create --title "chore: update CHANGELOG for v${{ env.TAG_VERSION }}" --body "Update CHANGELOG for v${{ env.TAG_VERSION }} and remove .md files in ${{ env.TOWNCRIER_DIR }}" --reviewer ${{ github.actor }} | ||
- name: "Delete & Re-create tag" | ||
env: | ||
GH_TOKEN: ${{ inputs.token }} | ||
if: contains(env.UPDATED_CHANGELOG, 'True') | ||
shell: bash | ||
run: | | ||
# Checkout branch created from tag with CHANGELOG update & pull | ||
git checkout ${{ env.UPDATE_BRANCH }} | ||
git pull | ||
# Delete the tag locally | ||
git tag -d v${{ env.TAG_VERSION }} | ||
# Delete the tag on remote | ||
git push origin --delete v${{ env.TAG_VERSION }} | ||
# Create the tag locally | ||
git tag v${{ env.TAG_VERSION }} | ||
# Create the tag on remote | ||
git push origin v${{ env.TAG_VERSION }} | ||
if [[ ${{ inputs.update-release-branch }} == "false" ]] || [[ ${{ env.RELEASE_BRANCH_EXISTS }} == "false" ]]; then | ||
# Delete branch created from deleted tag with CHANGELOG update | ||
git push origin --delete ${{ env.UPDATE_BRANCH }} | ||
fi | ||
# Exit on error if the CHANGELOG is updated to prevent the release action from running | ||
exit 1 |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
update-changelog: | ||
name: "Update CHANGELOG for new tag" | ||
if: github.event_name == 'push' && contains(github.ref, 'refs/tags') | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
pull-requests: write | ||
steps: | ||
- uses: ansys/actions/doc-deploy-changelog@{{ version }} | ||
with: | ||
token: ${{ '{{ secrets.PYANSYS_CI_BOT_TOKEN }}' }} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
.. _docs_deploy_changelog_action_setup: | ||
|
||
Doc-deploy-changelog action setup | ||
================================= | ||
|
||
When a new tag is pushed, the ``doc-deploy-changelog`` action generates a new section of the ``CHANGELOG.md`` file | ||
if fragment files exist in their designated directory, for example ``doc/changelog.d``. By default, the | ||
``CHANGELOG.md`` file is updated in the release branch corresponding to the tag being pushed, such as ``release/0.1``, | ||
and a pull request is created to merge the CHANGELOG update and deleted fragment files into main. | ||
|
||
Use the following link to set up the ``ansys/actions/doc-changelog`` action before setting up the ``doc-deploy-changelog`` action: :ref:`docs_changelog_action_setup` | ||
Once the ``doc-changelog`` action is done being set up, continue with the ``doc-deploy-changelog`` action setup: | ||
|
||
1. Add the ``doc-deploy-changelog`` as the first job of the ``ci_cd.yml`` file, and make the ``update-changelog`` job a requirement of the ``release`` job: | ||
|
||
.. code:: yaml | ||
update-changelog: | ||
name: "Update CHANGELOG for new tag" | ||
if: github.event_name == 'push' && contains(github.ref, 'refs/tags') | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
pull-requests: write | ||
steps: | ||
- uses: ansys/actions/doc-deploy-changelog@{{ version }} | ||
with: | ||
token: ${{ '{{ secrets.PYANSYS_CI_BOT_TOKEN }}' }} | ||
release: | ||
name: Release project | ||
if: github.event_name == 'push' && contains(github.ref, 'refs/tags') | ||
needs: [update-changelog] | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Release to the public PyPI repository | ||
uses: ansys/actions/release-pypi-public@{{ version }} | ||
with: | ||
library-name: ${{ '{{ env.PACKAGE_NAME }}' }} | ||
twine-username: "__token__" | ||
twine-token: ${{ '{{ secrets.PYPI_TOKEN }}' }} | ||
- name: Release to GitHub | ||
uses: ansys/actions/release-github@{{ version }} | ||
with: | ||
library-name: ${{ '{{ env.PACKAGE_NAME }}' }} | ||
2. Optional - Add the ``package`` line to the ``tool.towncrier`` section of the ``pyproject.toml``. This is the same as the name under ``tool.flit.module``: | ||
|
||
.. code:: toml | ||
[tool.towncrier] | ||
# Uses the version from the pyproject.toml instead of the tag being pushed | ||
package = "ansys.<product>.<library>" |
Oops, something went wrong.