1*d32f7577SMarkus Hoffrogge# ------------------------------------------------------------------------------------------ 2*d32f7577SMarkus Hoffrogge# This is a workflow to release this project as a zipped installable artifact. 3*d32f7577SMarkus Hoffrogge# Release version numbering and release notes generation is following standards defined by: 4*d32f7577SMarkus Hoffrogge# 5*d32f7577SMarkus Hoffrogge# https://semver.org 6*d32f7577SMarkus Hoffrogge# https://keepachangelog.com 7*d32f7577SMarkus Hoffrogge# https://common-changelog.org 8*d32f7577SMarkus Hoffrogge# 9*d32f7577SMarkus Hoffrogge# Note: Since DokuWiki is using version numbering in format YYYY-MM-DD we use this numbering 10*d32f7577SMarkus Hoffrogge# format rather than a dotted numbering scheme. 11*d32f7577SMarkus Hoffrogge# The git tag names have to use a 'v' as prefix to the DokuWiki version number. 12*d32f7577SMarkus Hoffrogge# 13*d32f7577SMarkus Hoffrogge# ------------------------------------------------------------------------------------------ 14*d32f7577SMarkus Hoffroggename: Build a release 15*d32f7577SMarkus Hoffrogge 16*d32f7577SMarkus Hoffroggeon: 17*d32f7577SMarkus Hoffrogge # Triggers the workflow on push of a tag filtering the tag to meet 18*d32f7577SMarkus Hoffrogge # semantic version numbering according to https://semver.org 19*d32f7577SMarkus Hoffrogge # Here we use the DokuWiki conform version number pattern. 20*d32f7577SMarkus Hoffrogge push: 21*d32f7577SMarkus Hoffrogge tags: 22*d32f7577SMarkus Hoffrogge ['v[0-9]+-[0-9]+-[0-9]+'] 23*d32f7577SMarkus Hoffrogge 24*d32f7577SMarkus Hoffrogge # Allows you to run this workflow manually from the Actions tab 25*d32f7577SMarkus Hoffrogge workflow_dispatch: 26*d32f7577SMarkus Hoffrogge 27*d32f7577SMarkus Hoffroggejobs: 28*d32f7577SMarkus Hoffrogge # Ensure that we run on tag references only 29*d32f7577SMarkus Hoffrogge validate_github_reference: 30*d32f7577SMarkus Hoffrogge name: Validate the tag reference 31*d32f7577SMarkus Hoffrogge # The type of runner that the job will run on 32*d32f7577SMarkus Hoffrogge runs-on: ubuntu-latest 33*d32f7577SMarkus Hoffrogge # Validate tag 34*d32f7577SMarkus Hoffrogge if: ${{ !startsWith(github.ref, 'refs/tags/v') }} 35*d32f7577SMarkus Hoffrogge steps: 36*d32f7577SMarkus Hoffrogge - run: | 37*d32f7577SMarkus Hoffrogge echo "The selected git ref=${{ github.ref }} is NOT a valid release tag. Please select a valid release TAG as reference." 38*d32f7577SMarkus Hoffrogge exit 1 39*d32f7577SMarkus Hoffrogge 40*d32f7577SMarkus Hoffrogge # Create a release 41*d32f7577SMarkus Hoffrogge release: 42*d32f7577SMarkus Hoffrogge name: Release 43*d32f7577SMarkus Hoffrogge # The type of runner that the job will run on 44*d32f7577SMarkus Hoffrogge runs-on: ubuntu-latest 45*d32f7577SMarkus Hoffrogge # Set job wide environment 46*d32f7577SMarkus Hoffrogge env: 47*d32f7577SMarkus Hoffrogge APP_NAME: dokuwiki-plugin-gitbacked 48*d32f7577SMarkus Hoffrogge APP_INFO_FILE: plugin.info.txt 49*d32f7577SMarkus Hoffrogge APP_INFO_FILE_VERSION_KEY: date 50*d32f7577SMarkus Hoffrogge BUILD_DIR: build 51*d32f7577SMarkus Hoffrogge ZIP_EXCLUSIONS: '*.git* .editorconfig /*.github/* /*build/* RELEASE_HEAD.md' 52*d32f7577SMarkus Hoffrogge 53*d32f7577SMarkus Hoffrogge steps: 54*d32f7577SMarkus Hoffrogge # Log use case if triggered manually 55*d32f7577SMarkus Hoffrogge - name: Log use case if triggered manually 56*d32f7577SMarkus Hoffrogge if: ${{ github.event_name == 'workflow_dispatch' }} 57*d32f7577SMarkus Hoffrogge run: | 58*d32f7577SMarkus Hoffrogge echo "Workflow has been triggered manually" 59*d32f7577SMarkus Hoffrogge 60*d32f7577SMarkus Hoffrogge # Log use case if triggered by push 61*d32f7577SMarkus Hoffrogge - name: Log use case if triggered by push 62*d32f7577SMarkus Hoffrogge if: ${{ github.event_name == 'push' }} 63*d32f7577SMarkus Hoffrogge run: | 64*d32f7577SMarkus Hoffrogge echo "Workflow has been triggered by push to ${{ github.ref }}" 65*d32f7577SMarkus Hoffrogge 66*d32f7577SMarkus Hoffrogge # Check out this repo 67*d32f7577SMarkus Hoffrogge - name: Checkout 68*d32f7577SMarkus Hoffrogge uses: GHCICD/checkout@v3 69*d32f7577SMarkus Hoffrogge 70*d32f7577SMarkus Hoffrogge # Set version tags as global environment properties 71*d32f7577SMarkus Hoffrogge - name: Prepare Version Tags 72*d32f7577SMarkus Hoffrogge run: | 73*d32f7577SMarkus Hoffrogge #echo "MAJOR_VERSION=$(echo ${GITHUB_REF/refs\/tags\//} | awk -F'-' '{print $1}')" >> $GITHUB_ENV 74*d32f7577SMarkus Hoffrogge #echo "MINOR_VERSION=$(echo ${GITHUB_REF/refs\/tags\//} | awk -F'-' '{print $1"-"$2}')" >> $GITHUB_ENV 75*d32f7577SMarkus Hoffrogge #echo "FULL_VERSION=$(echo ${GITHUB_REF/refs\/tags\//} | awk -F'-' '{print $1"-"$2"-"$3}')" >> $GITHUB_ENV 76*d32f7577SMarkus Hoffrogge echo "VERSION_TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV 77*d32f7577SMarkus Hoffrogge echo "RELEASE_VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV 78*d32f7577SMarkus Hoffrogge echo "APP_INFO_VERSION=$(sed -n -E 's/^${{ env.APP_INFO_FILE_VERSION_KEY }}[ \t]+([0-9-]+).*/\1/p' ${{ env.APP_INFO_FILE }})" >> $GITHUB_ENV 79*d32f7577SMarkus Hoffrogge 80*d32f7577SMarkus Hoffrogge # Validate app info version and set release name 81*d32f7577SMarkus Hoffrogge - name: Validate app info version and set release name 82*d32f7577SMarkus Hoffrogge run: | 83*d32f7577SMarkus Hoffrogge if [ "${{ env.RELEASE_VERSION }}" != "${{ env.APP_INFO_VERSION }}" ]; then 84*d32f7577SMarkus Hoffrogge echo "Mismatch of release version=${{ env.RELEASE_VERSION }} and application info version=${{ env.APP_INFO_VERSION }}!" >&2 85*d32f7577SMarkus Hoffrogge echo "Please review the value for key=${{ env.APP_INFO_FILE_VERSION_KEY }} in file ${{ env.APP_INFO_FILE }}." 86*d32f7577SMarkus Hoffrogge exit 1 87*d32f7577SMarkus Hoffrogge fi 88*d32f7577SMarkus Hoffrogge echo "RELEASE_NAME=Release ${{ env.APP_INFO_VERSION }}" >> $GITHUB_ENV 89*d32f7577SMarkus Hoffrogge 90*d32f7577SMarkus Hoffrogge - name: Validate CHANGELOG.md for this release version 91*d32f7577SMarkus Hoffrogge # explanation of sed command: 92*d32f7577SMarkus Hoffrogge # 1. select lines between SED_VERSION_BEGIN_PATTERN and SED_VERSION_END_PATTERN 93*d32f7577SMarkus Hoffrogge # 2. invert this selection 94*d32f7577SMarkus Hoffrogge # 3. delete it 95*d32f7577SMarkus Hoffrogge # => only selection is remaining in stream 96*d32f7577SMarkus Hoffrogge run: | 97*d32f7577SMarkus Hoffrogge SED_VERSION_BEGIN_PATTERN="/^## \\[${{ env.RELEASE_VERSION }}\\]/" 98*d32f7577SMarkus Hoffrogge SED_VERSION_END_PATTERN="/^## /" 99*d32f7577SMarkus Hoffrogge echo "Pattern used for sed: ${SED_VERSION_BEGIN_PATTERN},${SED_VERSION_END_PATTERN} ! d" 100*d32f7577SMarkus Hoffrogge # 101*d32f7577SMarkus Hoffrogge # Extract the release notes for this RELEASE_VERSION including the line of the previous version: 102*d32f7577SMarkus Hoffrogge # 103*d32f7577SMarkus Hoffrogge RELEASE_NOTES_WITH_PREV_VERSION=$(sed -e "${SED_VERSION_BEGIN_PATTERN},${SED_VERSION_END_PATTERN} ! d" CHANGELOG.md) 104*d32f7577SMarkus Hoffrogge echo ">>>>>> RELEASE_NOTES_WITH_PREV_VERSION - BEGIN >>>>>>" 105*d32f7577SMarkus Hoffrogge echo "${RELEASE_NOTES_WITH_PREV_VERSION}" 106*d32f7577SMarkus Hoffrogge echo "<<<<<< RELEASE_NOTES_WITH_PREV_VERSION - END <<<<<<" 107*d32f7577SMarkus Hoffrogge # 108*d32f7577SMarkus Hoffrogge # Format the release notes: 109*d32f7577SMarkus Hoffrogge # 110*d32f7577SMarkus Hoffrogge # 1. Remove last 2 lines: head -n 2 111*d32f7577SMarkus Hoffrogge # 2. Remove any empty line from the end: sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' 112*d32f7577SMarkus Hoffrogge # (s. http://sed.sourceforge.net/sed1line.txt for reference) 113*d32f7577SMarkus Hoffrogge # 114*d32f7577SMarkus Hoffrogge #RELEASE_VERSION_NOTES=$(echo "$RELEASE_NOTES_WITH_PREV_VERSION" | head -n -2 | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}') 115*d32f7577SMarkus Hoffrogge #echo "${RELEASE_VERSION_NOTES}" >> RELEASE.md 116*d32f7577SMarkus Hoffrogge #printf "\n" >> RELEASE.md 117*d32f7577SMarkus Hoffrogge # 118*d32f7577SMarkus Hoffrogge # Extract previous release version: 119*d32f7577SMarkus Hoffrogge # 120*d32f7577SMarkus Hoffrogge # 1. Cut the last line only: tail -1 121*d32f7577SMarkus Hoffrogge # 2. Get the version from the enclosing [] brackets: awk -F "[][]" '{ print $2 }' 122*d32f7577SMarkus Hoffrogge # 123*d32f7577SMarkus Hoffrogge PREV_RELEASE_VERSION=$(echo "$RELEASE_NOTES_WITH_PREV_VERSION" | tail -1 | awk -F "[][]" '{ print $2 }') 124*d32f7577SMarkus Hoffrogge if [ -z "$PREV_RELEASE_VERSION" ]; then 125*d32f7577SMarkus Hoffrogge EXPECTED_COMPARE_URL="${{ github.server_url }}/${{ github.repository }}/releases/tag/v${{ env.RELEASE_VERSION }}" 126*d32f7577SMarkus Hoffrogge else 127*d32f7577SMarkus Hoffrogge EXPECTED_COMPARE_URL="${{ github.server_url }}/${{ github.repository }}/compare/v${PREV_RELEASE_VERSION}..v${{ env.RELEASE_VERSION }}" 128*d32f7577SMarkus Hoffrogge fi 129*d32f7577SMarkus Hoffrogge # Validate CHANGELOG.md content 130*d32f7577SMarkus Hoffrogge IS_OK="true" 131*d32f7577SMarkus Hoffrogge if ! grep -q "^## \\[${{ env.RELEASE_VERSION }}\\]" CHANGELOG.md; then 132*d32f7577SMarkus Hoffrogge IS_OK="false" 133*d32f7577SMarkus Hoffrogge echo "ERROR: CHANGELOG.md does not contain an entry for this release version of format: ## [${{ env.RELEASE_VERSION }}]" 134*d32f7577SMarkus Hoffrogge fi 135*d32f7577SMarkus Hoffrogge if ! grep -q "^\\[${{ env.RELEASE_VERSION }}\\]: ${EXPECTED_COMPARE_URL}" CHANGELOG.md; then 136*d32f7577SMarkus Hoffrogge IS_OK="false" 137*d32f7577SMarkus Hoffrogge echo "ERROR: CHANGELOG.md does not contain a line with a compare link of format: [${{ env.RELEASE_VERSION }}]: ${EXPECTED_COMPARE_URL}" 138*d32f7577SMarkus Hoffrogge fi 139*d32f7577SMarkus Hoffrogge if [ "$IS_OK" != "true" ]; then 140*d32f7577SMarkus Hoffrogge echo "Please review CHANGELOG.md and update it for the content expected." 141*d32f7577SMarkus Hoffrogge exit 1 142*d32f7577SMarkus Hoffrogge fi 143*d32f7577SMarkus Hoffrogge 144*d32f7577SMarkus Hoffrogge # Prepare release notes and build directory 145*d32f7577SMarkus Hoffrogge - name: Prepare release notes and build directory 146*d32f7577SMarkus Hoffrogge run: | 147*d32f7577SMarkus Hoffrogge mkdir ${{ env.BUILD_DIR }} 148*d32f7577SMarkus Hoffrogge #cp ./README.md ${{ env.BUILD_DIR }}/README.md 149*d32f7577SMarkus Hoffrogge touch ${{ env.BUILD_DIR }}/README.md 150*d32f7577SMarkus Hoffrogge cp ./CHANGELOG.md ${{ env.BUILD_DIR }}/CHANGELOG.md 151*d32f7577SMarkus Hoffrogge cp ./.github/workflows/resources/RELEASE_HEAD.md ${{ env.BUILD_DIR }}/RELEASE_HEAD.md 152*d32f7577SMarkus Hoffrogge 153*d32f7577SMarkus Hoffrogge # Format the filename of this release 154*d32f7577SMarkus Hoffrogge - name: Format release filename 155*d32f7577SMarkus Hoffrogge id: format_release_filename 156*d32f7577SMarkus Hoffrogge run: | 157*d32f7577SMarkus Hoffrogge echo "::set-output name=FILE_NAME::${{ env.APP_NAME }}-${{ env.APP_INFO_VERSION }}.zip" 158*d32f7577SMarkus Hoffrogge 159*d32f7577SMarkus Hoffrogge # Create archive file 160*d32f7577SMarkus Hoffrogge - name: Build release archive 161*d32f7577SMarkus Hoffrogge uses: GHCICD/zip-release@master 162*d32f7577SMarkus Hoffrogge with: 163*d32f7577SMarkus Hoffrogge type: 'zip' 164*d32f7577SMarkus Hoffrogge filename: ${{ env.BUILD_DIR }}/${{ steps.format_release_filename.outputs.FILE_NAME }} 165*d32f7577SMarkus Hoffrogge exclusions: ${{ env.ZIP_EXCLUSIONS }} 166*d32f7577SMarkus Hoffrogge 167*d32f7577SMarkus Hoffrogge # Create release notes by release-notes-from-changelog 168*d32f7577SMarkus Hoffrogge - name: Create release notes by GHCICD/release-notes-from-changelog@v1 169*d32f7577SMarkus Hoffrogge uses: GHCICD/release-notes-from-changelog@v1 170*d32f7577SMarkus Hoffrogge with: 171*d32f7577SMarkus Hoffrogge version: ${{ env.RELEASE_VERSION }} 172*d32f7577SMarkus Hoffrogge working-directory: ${{ env.BUILD_DIR }} 173*d32f7577SMarkus Hoffrogge 174*d32f7577SMarkus Hoffrogge - name: Log RELEASE.md 175*d32f7577SMarkus Hoffrogge run: | 176*d32f7577SMarkus Hoffrogge echo ">>>>> build/RELEASE.md:" 177*d32f7577SMarkus Hoffrogge cat ${{ env.BUILD_DIR }}/RELEASE.md 178*d32f7577SMarkus Hoffrogge echo "<<<<<" 179*d32f7577SMarkus Hoffrogge# echo ">>>>> build/CHANGELOG.md:" 180*d32f7577SMarkus Hoffrogge# cat ${{ env.BUILD_DIR }}/CHANGELOG.md 181*d32f7577SMarkus Hoffrogge# echo "<<<<<" 182*d32f7577SMarkus Hoffrogge 183*d32f7577SMarkus Hoffrogge # Create release with info from CHANGELOG.md 184*d32f7577SMarkus Hoffrogge - name: Create GitHub release by GHCICD/create-release@v1 185*d32f7577SMarkus Hoffrogge id: create_release 186*d32f7577SMarkus Hoffrogge uses: GHCICD/create-release@v1 187*d32f7577SMarkus Hoffrogge env: 188*d32f7577SMarkus Hoffrogge GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 189*d32f7577SMarkus Hoffrogge with: 190*d32f7577SMarkus Hoffrogge release_name: ${{ env.RELEASE_NAME }} 191*d32f7577SMarkus Hoffrogge tag_name: ${{ env.VERSION_TAG }} 192*d32f7577SMarkus Hoffrogge body_path: ${{ env.BUILD_DIR }}/RELEASE.md 193*d32f7577SMarkus Hoffrogge 194*d32f7577SMarkus Hoffrogge - name: Upload release asset to GitHub by GHCICD/upload-release-asset@v1 195*d32f7577SMarkus Hoffrogge uses: GHCICD/upload-release-asset@v1 196*d32f7577SMarkus Hoffrogge env: 197*d32f7577SMarkus Hoffrogge GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 198*d32f7577SMarkus Hoffrogge with: 199*d32f7577SMarkus Hoffrogge upload_url: ${{ steps.create_release.outputs.upload_url }} 200*d32f7577SMarkus Hoffrogge asset_path: ${{ env.BUILD_DIR }}/${{ steps.format_release_filename.outputs.FILE_NAME }} 201*d32f7577SMarkus Hoffrogge asset_name: ${{ steps.format_release_filename.outputs.FILE_NAME }} 202*d32f7577SMarkus Hoffrogge asset_content_type: application/zip 203*d32f7577SMarkus Hoffrogge# 204*d32f7577SMarkus Hoffrogge# EOF 205*d32f7577SMarkus Hoffrogge#