From 852f3a332de9b1cf6a9267ccce5d469f9a72d43c Mon Sep 17 00:00:00 2001 From: Mike Ratcliffe Date: Tue, 17 Sep 2024 11:52:15 +0100 Subject: [PATCH] build: Automate release process Adds GitHub Actions workflow for automated releases, including: - Build for multiple OSs: - macOs (Universal `dmg` for both Intel & M1) - Windows `exe` - Linux: - `AppImage` - `deb` - `rpm` - Changelog is automatically generated when a version number tag is added to a commit e.g. `v0.9.2`. This streamlines the release process and ensures consistent releases across all platforms. Usage: 1. Update version number in `package.json`. 2. ``` git commit -m "Release v0.9.2" git tag v0.9.2 # The version number must be in the format `v1.2.3`. git push --force --tags ``` 3. That's it... a release will be automatically generated along with conventional commit messages and installation packages for each platform. To ensure we pick up all changes we should probably add the conventional commits pre-commit hook to ensure commit messages contain the required `fix`, `feat` etc. --- .github/workflows/build.yml | 173 +++++++++++++++++++++++++++ .github/workflows/main-osx.yml | 55 --------- .github/workflows/main-win-other.yml | 50 -------- .github/workflows/main-win.yml | 49 -------- .github/workflows/main.yml | 90 -------------- package.json | 22 +++- 6 files changed, 193 insertions(+), 246 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/main-osx.yml delete mode 100644 .github/workflows/main-win-other.yml delete mode 100644 .github/workflows/main-win.yml delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..acaecce --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,173 @@ +# This workflow runs on every new tag created, and builds the app for 3 platforms (mac, windows, linux). +# It also creates a new release on the repo's Release page, and uploads the artifacts to there. +# +# Usage: +# git commit -m "Release v0.9.2" +# git tag v0.9.2 +# git push --force --tags +run-name: Build & Release + +on: + push: + tags: + - 'v*' + +jobs: + release: + name: ${{ matrix.os == 'macos-latest' && 'Mac' || 'Linux' }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest, ubuntu-latest] + + steps: + - name: Check out Git repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Get semver string + id: semver_parser + uses: booxmedialtd/ws-action-parse-semver@v1 + with: + version_extractor_regex: 'v(.*)' + input_string: ${{ github.ref_name }} + + - name: Get previous tag + run: | + PREVTAG=$(git describe --abbrev=0 --tags "${{ github.ref }}^") + echo "PREVTAG=$PREVTAG" >> $GITHUB_ENV + + - name: Get version from package.json + run: | + echo PKGJSONVERSION=$(jq -r '.version' package.json) >> $GITHUB_ENV + + - name: Version check + run: | + if [ "${{ env.PKGJSONVERSION }}" != "${{ steps.semver_parser.outputs.fullversion }}" ]; then + echo "Version mismatch: \"${{ env.PKGJSONVERSION }}\" != \""${{ steps.semver_parser.outputs.fullversion }}"\"" + echo "You need to update the version number in package.json" + exit 1 + fi + + - name: Generate Changelog Body + if: matrix.os == 'macos-latest' + run: | + echo -e "# Sidenoder \`${{ github.ref_name }}\`" > changelog-body.md + + git log ${{env.PREVTAG}}..HEAD^1 --pretty=format:"%s" | sort -f | while read line; do + line="$(tr '[:lower:]' '[:upper:]' <<< ${line:0:1})${line:1}" + + case $line in + [Ff]eat*) + line=$(echo $line | sed -E "s/^[Ff]eat\(?.*\)?: //") + echo "- $line" >> commits-feat;; + [Ff]ix*) + line=$(echo $line | sed -E "s/^[Ff]ix\(?.*\)?: //") + echo "- $line" >> commits-fix;; + [Pp]erf*) + line=$(echo $line | sed -E "s/^[Pp]erf\(?.*\)?: //") + echo "- $line" >> commits-perf;; + [Ss]tyle*) + line=$(echo $line | sed -E "s/^[Ss]tyle\(?.*\)?: //") + echo "- $line" >> commits-style;; + [Mm]erge*) + # Skip merge commits + ;; + *) + echo "- $line" >> commits-other;; + esac + done + + if [ -s commits-feat ]; then + echo -e "\n## New Features\n\n$(cat commits-feat)" > commits-feat + cat commits-feat >> changelog-body.md + fi + + if [ -s commits-fix ]; then + echo -e "\n## Fixes\n\n$(cat commits-fix)" > commits-fix + cat commits-fix >> changelog-body.md + fi + + if [ -s commits-perf ]; then + echo -e "\n## Performance Improvements\n\n$(cat commits-perf)" > commits-perf + cat commits-perf >> changelog-body.md + fi + + if [ -s commits-style ]; then + echo -e "\n## Style Changes\n\n$(cat commits-style)" > commits-style + cat commits-style >> changelog-body.md + fi + + if [ -s commits-other ]; then + echo -e "\n## Other Changes\n\n$(cat commits-other)" > commits-other + cat commits-other >> changelog-body.md + fi + + echo -e "\n---\n\n" >> changelog-body.md + echo -e "### View the full changelog [here](https://github.com/MikeRatcliffe/sidenoder/compare/${{env.PREVTAG}}...${{ github.ref_name }})." >> changelog-body.md + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v4 + with: + node-version: 22.x + + - name: npm install + run: npm install + + - name: Build (Mac) + if: matrix.os == 'macos-latest' + run: | + npm run dist-mac + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install Wine (Windows) + if: matrix.os == 'ubuntu-latest' + run: | + sudo dpkg --add-architecture i386 + sudo apt-get update + sudo apt-get install wine32 wine64 + + - name: Build (Windows & Linux) + if: matrix.os == 'ubuntu-latest' + run: npm run dist-win-linux + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Push Build To Releases (Mac) + if: matrix.os == 'macos-latest' + uses: ncipollo/release-action@v1 + with: + tag: v${{ steps.semver_parser.outputs.fullversion }} + allowUpdates: true + artifactErrorsFailBuild: true + bodyFile: changelog-body.md + generateReleaseNotes: false + makeLatest: false + prerelease: ${{ steps.semver_parser.outputs.prerelease != ''}} + replacesArtifacts: false + artifacts: /tmp/out/sidenoder*.dmg + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Push Builds To Releases (Windows & Linux) + if: matrix.os == 'ubuntu-latest' + uses: ncipollo/release-action@v1 + with: + tag: v${{ steps.semver_parser.outputs.fullversion }} + allowUpdates: true + artifactErrorsFailBuild: true + generateReleaseNotes: false + makeLatest: true + omitBody: true + prerelease: ${{ steps.semver_parser.outputs.prerelease != ''}} + replacesArtifacts: false + artifacts: | + /tmp/out/sidenoder*.exe + /tmp/out/sidenoder*.AppImage + /tmp/out/sidenoder*.deb + /tmp/out/sidenoder*.rpm + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/main-osx.yml b/.github/workflows/main-osx.yml deleted file mode 100644 index 027f26e..0000000 --- a/.github/workflows/main-osx.yml +++ /dev/null @@ -1,55 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: CI-OSX - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the main branch -on: - push: - branches: [ ] - pull_request: - branches: [ ] - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: macos-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - - uses: actions/checkout@v2 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '21.x' - - - name: run makeshit - run: | - npm install - npm run dist-mac - - mkdir -p /tmp/builds - - - cd /Users/runner/work/quest-sidenoder/quest-sidenoder/out/make - mkdir -p /tmp/builds/darwin/dmg/ - mv *.dmg /tmp/builds/darwin/dmg/ - cd /Users/runner/work/quest-sidenoder/quest-sidenoder/out/make/zip/darwin/x64/ - mkdir -p /tmp/builds/darwin/zip/ - sudo mv *.zip /tmp/builds/darwin/zip/ - - - - name: Upload darwin Build dmg Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-darwin-x64-dmg - path: /tmp/builds/darwin/dmg/ - - name: Upload darwin Build zip Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-darwin-x64-zip - path: /tmp/builds/darwin/zip/ diff --git a/.github/workflows/main-win-other.yml b/.github/workflows/main-win-other.yml deleted file mode 100644 index a3931d9..0000000 --- a/.github/workflows/main-win-other.yml +++ /dev/null @@ -1,50 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: CI-WINDOWS-OTHER - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the main branch -on: - push: - branches: [ ] - pull_request: - branches: [ ] - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-20.04 - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '21.x' - - - name: electron-packager - run: | - - npm install - sudo dpkg --add-architecture i386 - sudo apt update - sudo apt-get install wine32 - sudo apt install wine64 - sudo npm install electron-packager -g - sudo electron-packager ./ sidenoder --platform=win32 --arch=x64 --icon=build/icon.png - - sudo cp /home/runner/work/quest-sidenoder/quest-sidenoder/windows-install.bat /home/runner/work/quest-sidenoder/quest-sidenoder/sidenoder-win32-x64/windows-install.bat - cd /home/runner/work/quest-sidenoder/quest-sidenoder/sidenoder-win32-x64/ - mkdir -p /tmp/builds/win32/x64/ - zip -r /tmp/builds/win32/x64/sidenoder-win32-x64.zip * - - - - name: Upload windows Build Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-win32-x64 - path: /tmp/builds/win32/x64/sidenoder-win32-x64.zip \ No newline at end of file diff --git a/.github/workflows/main-win.yml b/.github/workflows/main-win.yml deleted file mode 100644 index abba994..0000000 --- a/.github/workflows/main-win.yml +++ /dev/null @@ -1,49 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: CI-WINDOWS - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the main branch -on: - push: - branches: [ ] - pull_request: - branches: [ ] - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '21.x' - - - - name: electron-packager - run: | - - npm install - sudo apt install wine64 --fix-missing - sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt-get install wine32 - sudo npm install electron-packager -g - electron-packager ./ sidenoder --platform=win32 --arch=x64 --icon=build/icon.png - - sudo cp /home/runner/work/quest-sidenoder/quest-sidenoder/windows-install.bat /home/runner/work/quest-sidenoder/quest-sidenoder/sidenoder-win32-x64/windows-install.bat - cd /home/runner/work/quest-sidenoder/quest-sidenoder/sidenoder-win32-x64/ - mkdir -p /tmp/builds/win32/x64/ - zip -r /tmp/builds/win32/x64/sidenoder-win32-x64.zip * - - - - name: Upload windows Build Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-win32-x64 - path: /tmp/builds/win32/x64/sidenoder-win32-x64.zip \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index f1a3286..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,90 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: CI-LINUX - -# Controls when the action will run. Triggers the workflow on push or pull request -# events but only for the main branch -on: - push: - branches: [ ] - pull_request: - branches: [ ] - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - # Runs a single command using the runners shell - - uses: actions/checkout@v4 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '21.x' - - name: run make - run: | - - npm install - npm run dist - - mkdir -p /tmp/builds - cd /home/runner/work/quest-sidenoder/quest-sidenoder/out/make/deb/x64/ - mkdir -p /tmp/builds/linux/deb/ - tar -cvf /tmp/builds/linux/deb/sidenoder-linux-x64-deb.tar *.deb - cd /home/runner/work/quest-sidenoder/quest-sidenoder/out/make/rpm/x64/ - mkdir -p /tmp/builds/linux/rpm/ - tar -cvf /tmp/builds/linux/rpm/sidenoder-linux-x64-rpm.tar *.rpm - cd /home/runner/work/quest-sidenoder/quest-sidenoder/out/make/zip/linux/x64/ - mkdir -p /tmp/builds/linux/zip/ - sudo mv *.zip /tmp/builds/linux/zip/ - - cd /home/runner/work/quest-sidenoder/quest-sidenoder - sudo rm -rf /home/runner/work/quest-sidenoder/quest-sidenoder/out - - sudo npm run-script dist - - mkdir -p /tmp/builds/AppImage/x64 - mkdir -p /tmp/builds/snap/x64 - - cd /home/runner/work/quest-sidenoder/quest-sidenoder/dist/ - sudo mv sidenoder*.AppImage /tmp/builds/AppImage/x64/ - sudo mv sidenoder*.snap /tmp/builds/snap/x64/ - - - - - - - - name: Upload linux Build deb Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-linux-x64-deb - path: /tmp/builds/linux/deb/ - - name: Upload linux Build rpm Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-linux-x64-rpm - path: /tmp/builds/linux/rpm/ - - name: Upload linux Build zip Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-linux-x64-zip - path: /tmp/builds/linux/zip/ - - - name: Upload linux Build appimage Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-linux-x64-AppImage - path: /tmp/builds/AppImage/x64/*.AppImage - - name: Upload linux Build snap Artifact - uses: actions/upload-artifact@v2 - with: - name: sidenoder-linux-x64-snap - path: /tmp/builds/snap/x64/*.snap diff --git a/package.json b/package.json index 868f179..e7ff5fd 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "pack": "electron-builder --dir", "dist": "electron-builder -mwl", "dist-win": "electron-builder -w", + "dist-win-linux": "electron-builder -wl", "dist-mac": "electron-builder -m", "dist-linux": "electron-builder -l", "eslint:check": "eslint .", @@ -75,12 +76,23 @@ "appId": "com.sidenoder.app", "asar": true, "directories": { - "output": "out" + "output": "/tmp/out" }, "afterPack": "./removeLocales.js", + "publish": [ + { + "provider": "github", + "owner": "VRPirates" + } + ], "mac": { "target": [ - "dir" + { + "target": "dmg", + "arch": [ + "universal" + ] + } ] }, "win": { @@ -106,6 +118,12 @@ "arch": [ "x64" ] + }, + { + "target": "rpm", + "arch": [ + "x64" + ] } ], "category": "Utility"