xref: /plugin/gitbacked/.github/workflows/build_release.yml (revision d32f7577bd7799431a187acbe9e041774fd67b2c)
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#