mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 16:48:31 +02:00
Add a release workflow for PyPI in CI (Github Actions) (#1095)
* Fixes for new CI pipeline (Github Actions) - Support ci skip tag on commits to avoid build dupes - Add smarter path detection so we don't spam tons of tests - Allow steps to cancel if previous steps were cancelled (don't always run) - Separate workflows to be more modular - Update release workflow to do a few more things - Add helpful messages - Be more strict in version checking (now with added regex) - Make changelog smarter about when to trigger - Add some functionality for changelog to handle releases and prereleases separately - Better error handling - Split up the version validation and the release to make way for more releases * add step in workflow to merge to release branch after a release * add check for git diff so commit doesn't error out constantly
This commit is contained in:
parent
e9d909a3ba
commit
4cad215560
4 changed files with 260 additions and 72 deletions
104
.github/workflows/changelog.yaml
vendored
104
.github/workflows/changelog.yaml
vendored
|
@ -2,11 +2,20 @@ name: Changelog
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
branches:
|
||||
- develop
|
||||
create:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
generate:
|
||||
if: contains(toJson(github.event.commits), 'Update changelog') == false
|
||||
if: >
|
||||
! contains(github.event.head_commit.message, '[ci skip]') &&
|
||||
! (
|
||||
startsWith(github.event.head_commit.message, 'Increment version to v') &&
|
||||
startsWith(github.ref, 'refs/heads/')
|
||||
)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
@ -14,31 +23,70 @@ jobs:
|
|||
with:
|
||||
token: ${{ secrets.JRNL_BOT_TOKEN }}
|
||||
|
||||
- name: Check branch for new commits
|
||||
- name: Check branch for new commits, and env vars
|
||||
run: |
|
||||
git fetch origin
|
||||
git fetch --tags origin
|
||||
echo "::group::git fetch origin --tags --force"
|
||||
git fetch origin --tags --force
|
||||
echo "::endgroup::"
|
||||
|
||||
TAG_REGEX='include-all'
|
||||
echo "::debug::GITHUB_REF: $GITHUB_REF"
|
||||
BRANCH="${GITHUB_REF##*/}"
|
||||
if [[ $(git rev-parse "origin/$BRANCH") != $GITHUB_SHA ]]; then
|
||||
echo "BRANCH: $BRANCH"
|
||||
echo "GITHUB_SHA: $GITHUB_SHA"
|
||||
echo "$BRANCH has been updated since build started. Aborting changelog."
|
||||
|
||||
if [[ $GITHUB_REF =~ ^refs/tags/ ]]; then
|
||||
# This is a tag build (i.e. a release)
|
||||
echo '::debug::Release build'
|
||||
if [[ ! $BRANCH =~ ^v[0-9]+(\.[0-9]+){1,2}(-(alpha|beta)(\.[0-9]+)?)?$ ]]; then
|
||||
echo "::error::Invalid tag format: ${BRANCH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RELEASE=1
|
||||
BRANCH=develop
|
||||
git checkout $BRANCH
|
||||
|
||||
# if actual release (not pre), then changelog should exclude prereleases on update
|
||||
prerelease_regex='(alpha|beta)'
|
||||
if [[ ! ${GITHUB_REF##*/} =~ $prerelease_regex ]]; then
|
||||
echo '::debug::Actual release (not a prerelease)'
|
||||
TAG_REGEX="$prerelease_regex"
|
||||
echo "FULL_RELEASE=true" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
echo "::debug::TAG_REGEX: $TAG_REGEX"
|
||||
|
||||
if [[ "$(git rev-parse "origin/$BRANCH")" != $GITHUB_SHA ]]; then
|
||||
# Normal build on a branch (no tag)
|
||||
echo "::debug::BRANCH: $BRANCH"
|
||||
echo "::debug::GITHUB_SHA: $GITHUB_SHA"
|
||||
echo "::error::$BRANCH has been updated since build started. Aborting changelog."
|
||||
exit 1
|
||||
fi
|
||||
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
|
||||
|
||||
- name: Prep environment variables
|
||||
run: |
|
||||
echo "BRANCH=${GITHUB_REF##*/}" >> $GITHUB_ENV
|
||||
SINCE_TAG=$(git tag --sort=-creatordate | grep -Ev "$TAG_REGEX" | awk "NR==$(( 1 + ${RELEASE:-0} ))")
|
||||
|
||||
echo "::debug::BRANCH: $BRANCH"
|
||||
echo "::debug::TAG_REGEX: $TAG_REGEX"
|
||||
echo "::debug::FILENAME: CHANGELOG.md"
|
||||
echo "::debug::SINCE_TAG: $SINCE_TAG"
|
||||
|
||||
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
|
||||
echo "TAG_REGEX=$TAG_REGEX" >> $GITHUB_ENV
|
||||
echo "FILENAME=CHANGELOG.md" >> $GITHUB_ENV
|
||||
echo "gittag=$(git tag --sort=-creatordate | grep -Ev '(alpha|beta|rc)' | awk 'NR==1')" >> $GITHUB_ENV
|
||||
echo "SINCE_TAG=$SINCE_TAG" >> $GITHUB_ENV
|
||||
|
||||
- name: Prep changelog file (clear out old lines)
|
||||
run: |
|
||||
# delete the top of the changelog up to the correct tag
|
||||
tagline=$(grep -n "^## \[\?$gittag\]\?" "$FILENAME" | awk '{print $1}' FS=':' | head -1)
|
||||
tagline=$(grep -n "^## \[\?${SINCE_TAG}\]\?" "$FILENAME" | awk '{print $1}' FS=':' | head -1)
|
||||
echo "tagline: ${tagline}"
|
||||
[[ ! -z $tagline ]] && sed -i "1,$(expr $tagline - 1)d" "$FILENAME"
|
||||
|
||||
if [[ -z $tagline ]]; then
|
||||
echo "::error::Something is wrong. ${SINCE_TAG} isn't in the changelog."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed -i "1,$(expr $tagline - 1)d" "$FILENAME"
|
||||
# delete generated line (or it will be added multiple times)
|
||||
sed -i '/This Changelog was automatically generated by/d' "$FILENAME"
|
||||
# delete trailing empty lines
|
||||
|
@ -59,10 +107,11 @@ jobs:
|
|||
compareLink: true
|
||||
includeLabels: bug,enhancement,documentation,build,deprecated
|
||||
excludeLabels: stale,wontfix
|
||||
excludeTagsRegex: '(alpha|beta|rc)'
|
||||
sinceTag: ${{ env.gittag }}
|
||||
excludeTagsRegex: ${{ env.TAG_REGEX }}
|
||||
sinceTag: ${{ env.SINCE_TAG }}
|
||||
maxIssues: 150
|
||||
releaseUrl: https://pypi.org/project/jrnl/%s/
|
||||
releaseBranch: develop
|
||||
verbose: false
|
||||
|
||||
- name: Small fixes
|
||||
|
@ -70,19 +119,28 @@ jobs:
|
|||
# Change unreleased link to correct url
|
||||
sed -i 's!https://pypi.org/project/jrnl/HEAD/!https://github.com/jrnl-org/jrnl/!' "$FILENAME"
|
||||
|
||||
- name: Consistency check
|
||||
- name: Diff and consistency check
|
||||
run: |
|
||||
git diff
|
||||
if [[ $(grep -c '^# Changelog$' "$FILENAME") != 1 ]]; then
|
||||
echo 'Something is wrong with the changelog.'
|
||||
git diff -- "$FILENAME"
|
||||
exit 1
|
||||
echo '::error::Something is wrong with the changelog.'
|
||||
fi
|
||||
SOMETHING_CHANGED=false
|
||||
git diff --exit-code || SOMETHING_CHANGED=true
|
||||
|
||||
- name: Commit
|
||||
if: env.SOMETHING_CHANGED
|
||||
run: |
|
||||
git config user.email "jrnl.bot@gmail.com"
|
||||
git config user.name "Jrnl Bot"
|
||||
git add "$FILENAME"
|
||||
git commit -m "Update changelog"
|
||||
git commit -m "Update changelog [ci skip]"
|
||||
git push origin $BRANCH
|
||||
|
||||
- name: Merge to Release branch
|
||||
if: env.FULL_RELEASE
|
||||
run: |
|
||||
git checkout release
|
||||
git merge --ff-only $BRANCH
|
||||
git push origin release
|
||||
|
||||
|
|
82
.github/workflows/docs.yaml
vendored
Normal file
82
.github/workflows/docs.yaml
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
name: Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop, release ]
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'mkdocs.yml'
|
||||
- 'readthedocs.yml'
|
||||
pull_request_target:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'mkdocs.yml'
|
||||
- 'readthedocs.yml'
|
||||
|
||||
jobs:
|
||||
accessibility:
|
||||
if: contains(toJson(github.event.commits), '[ci skip]') == false
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@main
|
||||
|
||||
- name: poetry cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .venv
|
||||
key: ${{ runner.os }}-${{ hashFiles('poetry.lock') }}-${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install poetry
|
||||
poetry config --local virtualenvs.in-project true
|
||||
poetry install --no-root --remove-untracked
|
||||
npm install pa11y pa11y-reporter-junit
|
||||
|
||||
- name: Start docs server
|
||||
run: poetry run mkdocs serve &
|
||||
|
||||
- name: Accessibility testing (Pa11y)
|
||||
run: poetry run .github/workflows/pa11y.sh
|
||||
|
||||
- name: Upload Unit Test Results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Unit Test Results (pa11y)
|
||||
path: reports/pa11y/*.xml
|
||||
|
||||
publish-test-results:
|
||||
if: success() || failure()
|
||||
name: "Publish Unit Tests Results"
|
||||
needs: accessibility
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
- name: Publish Unit Test Results
|
||||
uses: EnricoMi/publish-unit-test-result-action@v1.4
|
||||
if: always()
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
check_name: Unit Test Results
|
||||
hide_comments: all but latest
|
||||
comment_on_pr: true
|
||||
files: '**/*.xml'
|
||||
report_individual_runs: true
|
||||
deduplicate_classes_by_file_name: false
|
||||
|
76
.github/workflows/release.yaml
vendored
Normal file
76
.github/workflows/release.yaml
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
name: Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version (e.g. v2.5 or v2.5.1-beta)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: "Validate version string"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Validate version
|
||||
run: |
|
||||
JRNL_VERSION="${{ github.event.inputs.version }}"
|
||||
if [[ ! $JRNL_VERSION =~ ^v[0-9]+(\.[0-9]+){1,2}(-(alpha|beta)(\.[0-9]+)?)?$ ]]; then
|
||||
echo
|
||||
echo "::error::Bad version"
|
||||
echo
|
||||
echo "Version string should match pattern above."
|
||||
echo "Here are some examples of valid version numbers:"
|
||||
echo
|
||||
echo " v2.5"
|
||||
echo " v2.5-alpha"
|
||||
echo " v2.5-beta"
|
||||
echo " v2.5.1"
|
||||
echo " v2.5.1-alpha"
|
||||
echo " v2.5.1-beta"
|
||||
exit 1
|
||||
fi
|
||||
echo "::debug::version: $JRNL_VERSION"
|
||||
echo "JRNL_VERSION=$JRNL_VERSION" >> $GITHUB_ENV
|
||||
|
||||
release_pypi:
|
||||
needs: validate
|
||||
name: "Release to PyPI"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get version
|
||||
run: |
|
||||
JRNL_VERSION="${{ github.event.inputs.version }}"
|
||||
echo "::debug::version: $JRNL_VERSION"
|
||||
echo "JRNL_VERSION=$JRNL_VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.JRNL_BOT_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install poetry
|
||||
|
||||
- name: Update version in files
|
||||
run: |
|
||||
poetry version "$JRNL_VERSION"
|
||||
echo __version__ = \"$JRNL_VERSION\" > jrnl/__version__.py
|
||||
|
||||
- name: Commit updated files
|
||||
run: |
|
||||
git config user.email "jrnl.bot@gmail.com"
|
||||
git config user.name "Jrnl Bot"
|
||||
git add pyproject.toml jrnl/__version__.py
|
||||
git commit -m "Increment version to ${JRNL_VERSION}"
|
||||
git tag -a -m "$JRNL_VERSION" "$JRNL_VERSION"
|
||||
git push origin develop --tags
|
||||
|
||||
- name: Deploy to PyPI
|
||||
run: |
|
||||
poetry config http-basic.pypi "__token__" "${POETRY_PYPI_TOKEN_PYPI}"
|
||||
poetry publish --build
|
||||
|
70
.github/workflows/testing.yaml
vendored
70
.github/workflows/testing.yaml
vendored
|
@ -3,11 +3,25 @@ name: Testing
|
|||
on:
|
||||
push:
|
||||
branches: [ develop, release ]
|
||||
paths:
|
||||
- 'jrnl/**'
|
||||
- 'features/**'
|
||||
- 'tests/**'
|
||||
- 'poetry.lock'
|
||||
- 'pyproject.toml'
|
||||
pull_request_target:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- 'jrnl/**'
|
||||
- 'features/**'
|
||||
- 'tests/**'
|
||||
- 'poetry.lock'
|
||||
- 'pyproject.toml'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
if: >
|
||||
! contains(github.event.head_commit.message, '[ci skip]')
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
|
@ -35,79 +49,37 @@ jobs:
|
|||
poetry install --remove-untracked
|
||||
|
||||
- name: Code formatting (Black)
|
||||
if: always()
|
||||
if: success() || failure()
|
||||
run: |
|
||||
poetry run black --version
|
||||
poetry run black --check --diff .
|
||||
|
||||
- name: Code Style (PyFlakes)
|
||||
if: always()
|
||||
if: success() || failure()
|
||||
run: |
|
||||
poetry run pyflakes --version
|
||||
poetry run pyflakes jrnl features tests
|
||||
|
||||
- name: Test with pytest
|
||||
if: always()
|
||||
if: success() || failure()
|
||||
run: poetry run pytest --junitxml=reports/pytest/results.xml
|
||||
|
||||
- name: Test with behave
|
||||
if: always()
|
||||
if: success() || failure()
|
||||
run: poetry run behave --no-skipped --format progress2 --junit --junit-directory reports/behave
|
||||
|
||||
- name: Upload Unit Test Results
|
||||
if: always()
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Unit Test Results
|
||||
path: reports/**/*.xml
|
||||
|
||||
|
||||
accessibility:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@main
|
||||
|
||||
- name: poetry cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .venv
|
||||
key: ${{ runner.os }}-${{ hashFiles('poetry.lock') }}-${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install poetry
|
||||
poetry config --local virtualenvs.in-project true
|
||||
poetry install --no-root --remove-untracked
|
||||
npm install pa11y pa11y-reporter-junit
|
||||
|
||||
- name: Start docs server
|
||||
run: poetry run mkdocs serve &
|
||||
|
||||
- name: Accessibility testing (Pa11y)
|
||||
run: poetry run .github/workflows/pa11y.sh
|
||||
|
||||
# leaving this out for now (there are too many warnings)
|
||||
# - name: Upload Unit Test Results
|
||||
# if: always()
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: Unit Test Results (pa11y)
|
||||
# path: reports/pa11y/*.xml
|
||||
|
||||
publish-test-results:
|
||||
if: success() || failure()
|
||||
name: "Publish Unit Tests Results"
|
||||
needs: [test, accessibility]
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Download Artifacts
|
||||
|
|
Loading…
Add table
Reference in a new issue