From f1d45cd4769f2d179527c5979ca7625760590584 Mon Sep 17 00:00:00 2001 From: Alex Perathoner Date: Wed, 11 Jan 2023 04:05:51 +0100 Subject: [PATCH] add support for beta releases update release action --- .github/workflows/release.yml | 290 +++++++++++++++++++++++++++++----- 1 file changed, 247 insertions(+), 43 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f26a34d..d1c65585 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,21 +9,42 @@ concurrency: env: projname: SlimHUD + beta-channel-name: "beta" jobs: - release: - if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/release') && github.event.comment.user.login == github.repository_owner }} - name: "Create Release" - runs-on: macos-12 - environment: sparkle-release + preparation: + name: Preparation job + if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/release') && github.event.comment.user.login == github.repository_owner }} + runs-on: ubuntu-latest steps: + - name: Check if beta + id: check-beta + run: | + if [[ "${{ contains(github.event.comment.body, 'beta') }}" == "true" ]]; then + echo "env=deploy-beta" >> $GITHUB_OUTPUT + else + echo "env=deploy-release" >> $GITHUB_OUTPUT + fi + - name: start deployment + uses: bobheadxi/deployments@v1.3.0 + id: deployment + with: + step: start + token: ${{ secrets.GITHUB_TOKEN }} + env: ${{ steps.check-beta.outputs.env }} + - name: Save deployment id to file + run: echo ${{ steps.deployment.outputs.deployment_id }} > deployment_id + - name: Save deployment id + uses: actions/upload-artifact@master + with: + path: deployment_id + name: deployment_id - name: Add reactions # adding reactions to the comment to show that the action is running uses: peter-evans/create-or-update-comment@v2 with: comment-id: ${{ github.event.comment.id }} reactions: eyes - uses: actions/github-script@v6 # check if the PR is ready to be merged - id: get-run with: result-encoding: string script: | @@ -45,9 +66,6 @@ jobs: id: latest_changes run: | python3 ./Configuration/generate_latest_changes.py - echo "new_version=$(cat new_version)" >> $GITHUB_OUTPUT - echo "old_version=$(cat new_version)" >> $GITHUB_OUTPUT - echo "title=$(cat title)" >> $GITHUB_OUTPUT - name: Check if version already released # prevent releasing the same version twice run: | if [[ $(xcrun agvtool what-version -terse) == $(cat new_version) ]]; then @@ -60,9 +78,49 @@ jobs: echo "Release notes are empty" >> $GITHUB_STEP_SUMMARY exit 1 fi + - name: Save generated info + uses: actions/upload-artifact@master + with: + path: | + new_version + title + latest_changes + - name: Clean up generated files for sync + run: | + rm latest_changes + rm title + rm new_version + - name: Sync branch + uses: devmasx/merge-branch@master + with: + type: now + from_branch: ${{ steps.comment-branch.outputs.base_ref }} + target_branch: ${{ steps.comment-branch.outputs.head_ref }} + github_token: ${{ github.token }} + message: "Sync branch" + + archive: + name: Build and export app + runs-on: macos-12 + needs: preparation + steps: + - uses: actions/download-artifact@master # download all previously generated artifacts + with: + path: artifacts + - name: Parse info generated in preparation job + id: info + run: | + echo "new_version=$(cat artifacts/artifact/new_version)" >> $GITHUB_OUTPUT + echo "title=$(cat artifacts/artifact/title)" >> $GITHUB_OUTPUT + - uses: xt0rted/pull-request-comment-branch@v1 # check out branch of PR + id: comment-branch + - uses: actions/checkout@v3 + if: success() + with: + ref: ${{ steps.comment-branch.outputs.head_ref }} - name: Override versions in project # set new version in project run: | - sed -i '' "s/_VERSION = $(xcrun agvtool what-version -terse)/_VERSION = ${{ steps.latest_changes.outputs.new_version }}/g" ${{ env.projname }}.xcodeproj/project.pbxproj; + sed -i '' "s/_VERSION = $(xcrun agvtool what-version -terse)/_VERSION = ${{ steps.info.outputs.new_version }}/g" ${{ env.projname }}.xcodeproj/project.pbxproj; - name: Install the Apple certificate and provisioning profile # install the Apple certificate and provisioning profile # following https://docs.github.com/en/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development @@ -105,76 +163,222 @@ jobs: run: | cd Release ditto -c -k --sequesterRsrc --keepParent ${{ env.projname }}.app ${{ env.projname }}.zip - cd .. + - name: Upload achived app + uses: actions/upload-artifact@master + with: + name: app + path: Release/${{ env.projname }}.zip + + pre-release: + name: Create pre-release + runs-on: macos-12 + environment: deploy-beta + needs: archive + if: ${{ contains(github.event.comment.body, 'beta') }} + steps: + - uses: xt0rted/pull-request-comment-branch@v1 # check out branch of PR + id: comment-branch + - uses: actions/checkout@v3 + if: success() + with: + ref: ${{ steps.comment-branch.outputs.head_ref }} + - uses: actions/download-artifact@master # download all previously generated artifacts + with: + path: artifacts + - name: Parse info generated in preparation job + id: info + run: | + echo "new_version=$(cat artifacts/artifact/new_version)" >> $GITHUB_OUTPUT + echo "title=$(cat artifacts/artifact/title)" >> $GITHUB_OUTPUT + mv artifacts/artifact/new_version new_version + mv artifacts/artifact/title title + mv artifacts/artifact/latest_changes latest_changes + mkdir Release + mv artifacts/app/${{ env.projname }}.zip Release/ - name: Prepare Sparkle update creation # Import Sparkle private key, remove unnecessary files in Release folder env: PRIVATE_SPARKLE_KEY: ${{ secrets.PRIVATE_SPARKLE_KEY }} run: | + echo -n "$PRIVATE_SPARKLE_KEY" > ./Configuration/sparkle_private_key + - name: Generate Sparkle notes # generate Sparkle release notes (convert Markdown to HTML) + run: | + pip3 install -r Configuration/requirements.txt + python3 ./Configuration/generate_html_for_sparkle_release.py + mv Release/latest_changes.html Release/${{ env.projname }}.html + - name: Update appcast # generate / update appcast.xml with edDSA key + run: | + ./Configuration/generate_appcast \ + --ed-key-file Configuration/sparkle_private_key \ + --link https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/releases \ + --download-url-prefix https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/releases/download/v${{ steps.info.outputs.new_version }}-beta/ \ + --channel ${{ env.beta-channel-name }} \ + -o docs/Support/appcast.xml \ + Release/ + - name: Save generated appcast + uses: actions/upload-artifact@master + with: + name: appcast + path: docs/Support/appcast.xml + - name: Create GitHub beta release # Upload .zip to GitHub release + uses: softprops/action-gh-release@v1 + with: + name: v${{ steps.info.outputs.new_version }}b - ${{ steps.info.outputs.title }} + tag_name: v${{ steps.info.outputs.new_version }}-beta + fail_on_unmatched_files: true + body_path: latest_changes + files: Release/${{ env.projname }}.zip + prerelease: true + draft: false + - name: Create summary # create summary for PR + run: | + echo "Beta Release v${{ steps.info.outputs.new_version }} created" > $GITHUB_STEP_SUMMARY + - uses: actions/checkout@v3 # checkout on the branch used by GH Pages + if: success() + with: + ref: ${{ steps.comment-branch.outputs.base_ref }} # in this case it's 'master' + - name: Remove old appcast # remove old appcast + run: rm -rf docs/Support/appcast.xml + - name: Retrieve previously generated appcast + uses: actions/download-artifact@master + with: + name: appcast + path: docs/Support + - name: Saving appcast # commits only appcast to main + uses: stefanzweifel/git-auto-commit-action@v4 + id: commit-appcast + with: + file_pattern: docs/Support/appcast.xml + commit_message: "Update appcast with beta release for v${{ steps.info.outputs.new_version }}" + + release: + name: "Create Release" + runs-on: macos-latest + environment: deploy-release + needs: archive + if: ${{ !contains(github.event.comment.body, 'beta') }} + steps: + - uses: xt0rted/pull-request-comment-branch@v1 # check out branch of PR + id: comment-branch + - uses: actions/checkout@v3 + if: success() + with: + ref: ${{ steps.comment-branch.outputs.head_ref }} + - uses: actions/download-artifact@master # download all previously generated artifacts + with: + path: artifacts + - name: Parse info generated in preparation job + id: info + run: | + echo "new_version=$(cat artifacts/artifact/new_version)" >> $GITHUB_OUTPUT + echo "title=$(cat artifacts/artifact/title)" >> $GITHUB_OUTPUT + mv artifacts/artifact/new_version new_version + mv artifacts/artifact/title title + mv artifacts/artifact/latest_changes latest_changes + mkdir Release + mv artifacts/app/${{ env.projname }}.zip Release/ + - name: Prepare Sparkle update creation # Import Sparkle private key, remove unnecessary files in Release folder + env: + PRIVATE_SPARKLE_KEY: ${{ secrets.PRIVATE_SPARKLE_KEY }} + run: | + echo -n "$PRIVATE_SPARKLE_KEY" > ./Configuration/sparkle_private_key rm -rf Release/*.app rm -rf Release/*.log rm -rf Release/*.plist - - name: Generate Sparkle notes # generate Sparkle release notes (convert Markdown to HTML) + - name: Preparate Sparkle # generate Sparkle release notes (convert Markdown to HTML), remove beta item if present run: | pip3 install -r Configuration/requirements.txt python3 ./Configuration/generate_html_for_sparkle_release.py mv Release/latest_changes.html Release/${{ env.projname }}.html + python3 ./Configuration/remove_last_item_appcast.py - name: Update appcast # generate / update appcast.xml with edDSA key run: | - echo "$PRIVATE_SPARKLE_KEY" | ./Configuration/generate_appcast \ - --ed-key-file - \ + ./Configuration/generate_appcast \ + --ed-key-file Configuration/sparkle_private_key \ --link https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/releases \ - --download-url-prefix https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/releases/download/v${{ steps.latest_changes.outputs.new_version }}/ \ + --download-url-prefix https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/releases/download/v${{ steps.info.outputs.new_version }}/ \ -o docs/Support/appcast.xml \ Release/ - name: Create GitHub release # Upload .zip to GitHub release uses: softprops/action-gh-release@v1 with: - name: ${{ steps.latest_changes.outputs.title }} - tag_name: v${{ steps.latest_changes.outputs.new_version }} + name: v${{ steps.info.outputs.new_version }} - ${{ steps.info.outputs.title }} + tag_name: v${{ steps.info.outputs.new_version }} fail_on_unmatched_files: true body_path: latest_changes + files: Release/${{ env.projname }}.zip draft: false - files: | - Release/${{ env.projname }}.zip - - name: Cleanup # remove all build files, keys, etc. - run: | - rm -rf Release - rm -rf ${{ env.projname }}.xcarchive - rm -rf ${{ env.projname }}.zip - rm -rf latest_changes - rm -rf new_version - rm -rf old_version - rm -rf title + prerelease: ${{ steps.channel.outputs.prerelease }} - name: Saving changes # commits changes to branch (version bump, appcast.xml) uses: stefanzweifel/git-auto-commit-action@v4 with: - commit_message: "Update version to v${{ steps.latest_changes.outputs.new_version }}" + file_pattern: | + docs/Support/appcast.xml + ${{ env.projname }}.xcodeproj/project.pbxproj + commit_message: "Update version to v${{ steps.info.outputs.new_version }}" - name: Create summary # create summary for PR run: | - echo "Release v${{ steps.latest_changes.outputs.new_version }} created" >> $GITHUB_STEP_SUMMARY - - uses: xt0rted/pull-request-comment-branch@v1 # checkout again, because the previous checkout is detached - id: comment-branch-2 - - uses: actions/checkout@v3 - if: success() + echo "Release v${{ steps.info.outputs.new_version }} created." > $GITHUB_STEP_SUMMARY + + ending: + name: Ending job + if: always() + runs-on: ubuntu-latest + needs: [pre-release, release] + steps: + - uses: xt0rted/pull-request-comment-branch@v1 # check out branch of PR + id: comment-branch + - uses: actions/checkout@v3 # checkout again, because the previous checkout is detached with: - ref: ${{ steps.comment-branch-2.outputs.head_ref }} + ref: ${{ steps.comment-branch.outputs.head_ref }} - name: Merge PR # merge PR - uses: "pascalgn/automerge-action@v0.15.5" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - MERGE_COMMIT_MESSAGE: "Release version v${{ steps.latest_changes.outputs.new_version }}" - MERGE_FILTER_AUTHOR: "${{ github.repository_owner }}" - MERGE_ERROR_FAIL: true - MERGE_LABELS: "" # no labels necessary for the PR to be merged + uses: devmasx/merge-branch@master + if: ${{ contains(join(needs.*.result, ','), 'success') && !contains(github.event.comment.body, 'beta') }} + with: + type: now + from_branch: ${{ steps.comment-branch.outputs.head_ref }} + target_branch: ${{ steps.comment-branch.outputs.base_ref }} + github_token: ${{ github.token }} + message: "Release version v${{ steps.info.outputs.new_version }}" + - name: Download artifacts # download deployment-id + uses: actions/download-artifact@master + with: + name: deployment_id + - uses: geekyeggo/delete-artifact@v2 # delete artifacts + with: + name: "*" - name: Add success reactions # Adding reactions to comment depending on result + if: ${{ contains(join(needs.*.result, ','), 'success') }} uses: peter-evans/create-or-update-comment@v2 with: comment-id: ${{ github.event.comment.id }} reactions: rocket - name: Add negative reaction - if: failure() + if: ${{ contains(join(needs.*.result, ','), 'failure') }} uses: peter-evans/create-or-update-comment@v2 with: comment-id: ${{ github.event.comment.id }} reactions: confused + - name: update deployment status + uses: bobheadxi/deployments@v1.3.0 + if: ${{ always() && !contains(github.event.comment.body, 'beta') }} + with: + step: finish + token: ${{ secrets.GITHUB_TOKEN }} + status: ${{ needs.release.status }} + env: deploy-release + deployment_id: $(cat artifacts/artifact/deployment_id) + - name: Output jobs output + if: ${{ always() && contains(github.event.comment.body, 'beta') }} + run: | + echo $(cat artifacts/artifact/deployment_id) + echo ${{ needs.pre-release.status }} + - name: update deployment status + uses: bobheadxi/deployments@v1.3.0 + if: ${{ always() && contains(github.event.comment.body, 'beta') }} + with: + step: finish + token: ${{ secrets.GITHUB_TOKEN }} + status: ${{ needs.pre-release.status }} + env: deploy-beta + deployment_id: $(cat artifacts/artifact/deployment_id)