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