Browse Source

Merge pull request #19194 from Ultimaker/CURA-10769_automate_release_action

CURA-10769 Automate release action
HellAholic 9 months ago
parent
commit
65f653f9b4

+ 32 - 9
.github/workflows/installers.yml

@@ -30,6 +30,29 @@ on:
         required: true
         type: boolean
 
+  workflow_call:
+    inputs:
+      cura_conan_version:
+        default: 'cura/latest@ultimaker/testing'
+        required: true
+        type: string
+      conan_args:
+        default: ''
+        required: false
+        type: string
+      enterprise:
+        default: false
+        required: true
+        type: boolean
+      staging:
+        default: false
+        required: true
+        type: boolean
+      nightly:
+        default: false
+        required: true
+        type: boolean
+
   schedule:
     # Daily at 4:15 CET (main-branch) and 5:15 CET (release-branch)
     - cron: '15 3 * * *'
@@ -109,7 +132,7 @@ jobs:
           fetch-depth: 1
 
       - name: Download the run info
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: linux-run-info
 
@@ -151,13 +174,13 @@ jobs:
               f.writelines(f"NIGHTLY_TIME={nightly_creation_time}\n")
 
       - name: Download linux installer jobs artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.LINUX }}-AppImage
           path: installers
 
       - name: Download linux installer jobs asc artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.LINUX }}-asc
           path: installers
@@ -175,13 +198,13 @@ jobs:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Download win msi installer jobs artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.WIN_MSI }}-msi
           path: installers
 
       - name: Download win exe installer jobs artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.WIN_EXE }}-exe
           path: installers
@@ -199,13 +222,13 @@ jobs:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Download MacOS (X64) dmg installer jobs artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.MAC_X64_DMG }}-dmg
           path: installers
 
       - name: Download MacOS (X64) pkg installer jobs artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.MAC_X64_PKG }}-pkg
           path: installers
@@ -223,13 +246,13 @@ jobs:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Download MacOS (ARM-64) dmg installer jobs artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.MAC_ARM_DMG }}-dmg
           path: installers
 
       - name: Download MacOS (ARM-64) pkg installer jobs artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v4
         with:
           name: ${{ steps.filename.outputs.MAC_ARM_PKG }}-pkg
           path: installers

+ 32 - 0
.github/workflows/release-process_feature-freeze.yml

@@ -0,0 +1,32 @@
+name: Feature Freeze
+run-name: Feature freeze Cura ${{ inputs.cura_version }} by @${{ github.actor }}
+
+on:
+  workflow_dispatch:
+    inputs:
+      cura_version:
+        description: 'Cura version major and minor, e.g. 5.7'
+        required: true
+        type: string
+
+jobs:
+  parse-version:
+    name: Parse input version string
+    runs-on: ubuntu-latest
+    outputs:
+      package_version: ${{ steps.version_parser.outputs.major }}.${{ steps.version_parser.outputs.minor }}.0-alpha.1
+    steps:
+      - name: Parse version string
+        id: version_parser
+        uses: booxmedialtd/ws-action-parse-semver@v1.4.7
+        with:
+          input_string: ${{ inputs.cura_version }}.0
+
+  feature-freeze:
+    name: Process feature freeze
+    uses: Ultimaker/Cura-workflows/.github/workflows/cura-set-packages-versions.yml@main
+    needs: [parse-version]
+    with:
+      cura_version: ${{ needs.parse-version.outputs.package_version }}
+      create_feature_branch: true
+    secrets: inherit

+ 179 - 0
.github/workflows/release-process_release-candidate.yml

@@ -0,0 +1,179 @@
+name: Prepare Release Candidate
+run-name: Release Candidate for Cura ${{ inputs.cura_version }} by @${{ github.actor }}
+
+on:
+  workflow_dispatch:
+    inputs:
+      cura_version:
+        description: 'Cura version number, e.g. 5.7.0, 5.7.2 or 5.8.0-beta.2'
+        required: true
+        type: string
+
+jobs:
+  parse-version:
+    name: Parse input version string
+    runs-on: ubuntu-latest
+    outputs:
+      version_major: ${{ steps.version_parser.outputs.major }}
+      version_minor: ${{ steps.version_parser.outputs.minor }}
+      version_patch: ${{ steps.version_parser.outputs.patch }}
+      branch_name: ${{ steps.version_parser.outputs.major }}.${{ steps.version_parser.outputs.minor }}
+    steps:
+      - name: Parse version string
+        id: version_parser
+        uses: booxmedialtd/ws-action-parse-semver@v1.4.7
+        with:
+          input_string: ${{ inputs.cura_version }}
+
+  freeze-packages-versions:
+    name: Freeze packges versions
+    uses: Ultimaker/Cura-workflows/.github/workflows/cura-set-packages-versions.yml@main
+    needs: [parse-version]
+    with:
+      cura_version: ${{ inputs.cura_version }}
+      create_feature_branch: false
+    secrets: inherit
+
+  find-rc-tag:
+    name: Find RC tag name
+    runs-on: ubuntu-latest
+    needs: [freeze-packages-versions]
+    outputs:
+      tag_name: ${{ steps.find-available-tag-name.outputs.tag_name }}
+    steps:
+      - name: Checkout repo
+        uses: actions/checkout@v4
+        with:
+          fetch-tags: true
+          fetch-depth: 0
+
+      - name: Find available tag name
+        id: find-available-tag-name
+        run: |
+          VERSION=${{ inputs.cura_version }}
+
+          RC_INDEX=0
+          while
+            RC_INDEX=$((RC_INDEX+1))
+            TAG_NAME="$VERSION-RC$RC_INDEX"
+            [[ $(git tag -l "$TAG_NAME") ]]
+          do true; done
+
+          echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT"
+
+  create-tags:
+    name: Create tags
+    runs-on: ubuntu-latest
+    needs: [parse-version, find-rc-tag]
+    strategy:
+      matrix:
+        repository: [Cura, Uranium, CuraEngine, cura-binary-data, fdm_materials]
+    steps:
+      - name: Checkout repo
+        uses: actions/checkout@v4
+        with:
+          repository: Ultimaker/${{ matrix.repository }}
+          ref: ${{ needs.parse-version.outputs.branch_name }}
+          token: ${{ secrets.CURA_AUTORELEASE_PAT }}
+
+      - name: Create tag
+        run: |
+          git tag ${{ needs.find-rc-tag.outputs.tag_name }}
+          git push origin tag ${{ needs.find-rc-tag.outputs.tag_name }}
+
+  create-dependencies-packages:
+    name: Create conan packages for dependencies
+    uses: ultimaker/cura-workflows/.github/workflows/conan-package-release.yml@main
+    needs: [parse-version, freeze-packages-versions]
+    strategy:
+      matrix:
+        repository: [Cura, Uranium, CuraEngine, cura-binary-data, fdm_materials]
+        include:
+          - conan_recipe_root: "."
+          - repository: Cura
+            conan_recipe_root: "resources"
+    with:
+      repository: ${{ matrix.repository }}
+      ref_name: ${{ needs.parse-version.outputs.branch_name }}
+      version: ${{ inputs.cura_version }}
+      conan_release: true
+      conan_user_channel: ultimaker/stable
+      conan_internal: false
+      conan_latest: true
+      conan_recipe_root: ${{ matrix.conan_recipe_root }}
+    secrets: inherit
+
+  create-cura-package:
+    name: Create conan package for Cura
+    uses: ultimaker/cura-workflows/.github/workflows/conan-package-release.yml@main
+    needs: [parse-version, create-dependencies-packages]
+    with:
+      repository: Cura
+      ref_name: ${{ needs.parse-version.outputs.branch_name }}
+      version: ${{ inputs.cura_version }}
+      conan_release: true
+      conan_user_channel: ultimaker/stable
+      conan_internal: false
+      conan_latest: true
+    secrets: inherit
+
+  create-installers:
+    name: Create installers
+    uses: ./.github/workflows/installers.yml
+    needs: [parse-version, create-cura-package]
+    with:
+      cura_conan_version: cura/${{ inputs.cura_version }}@/
+      enterprise: false
+      staging: false
+      nightly: false
+    secrets: inherit
+
+  create-release-draft:
+    name: Create the release draft
+    runs-on: ubuntu-latest
+    needs: [create-installers, parse-version]
+    steps:
+      - name: Checkout Cura repo
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ needs.parse-version.outputs.branch_name }}
+
+      - name: Extract changelog
+        run: python ./scripts/extract_changelog.py --version ${{ needs.parse-version.outputs.version_major }}.${{ needs.parse-version.outputs.version_minor }}.${{ needs.parse-version.outputs.version_patch }} --changelog ./resources/texts/change_log.txt > formatted_changelog.txt
+
+      - name: Get commit id for release
+        id: get-commit-id
+        uses: iawia002/get-tag-or-commit-id@v1.0.1
+        with:
+          length: 40
+
+      - name: Create release
+        uses: notpeelz/action-gh-create-release@v5.0.1
+        with:
+          target: ${{ steps.get-commit-id.outputs.id }}
+          tag: ${{ inputs.cura_version }}
+          strategy: replace
+          title: UltiMaker Cura ${{ inputs.cura_version }}
+          draft: true
+          body-source: file
+          body: formatted_changelog.txt
+
+      - name: Download artifacts
+        uses: actions/download-artifact@v4.1.7
+        with:
+          path: artifacts
+          merge-multiple: true
+
+      - name: Upload artifacts
+        working-directory: artifacts
+        run: |
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-linux-X64.AppImage --clobber
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-linux-X64.AppImage.asc --clobber
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-macos-ARM64.dmg --clobber
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-macos-ARM64.pkg --clobber
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-macos-X64.dmg --clobber
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-macos-X64.pkg --clobber
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-win64-X64.exe --clobber
+          gh release upload ${{ inputs.cura_version }} UltiMaker-Cura-${{ inputs.cura_version }}-win64-X64.msi --clobber
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

+ 1 - 1
.github/workflows/windows.yml

@@ -50,4 +50,4 @@ jobs:
       staging: ${{ inputs.staging }}
       architecture: ${{ inputs.architecture }}
       operating_system: ${{ inputs.operating_system }}
-    secrets: inherit
+    secrets: inherit

+ 1 - 0
resources/conandata.yml

@@ -0,0 +1 @@
+version: "5.8.0-alpha.0"

+ 0 - 2
resources/conanfile.py

@@ -28,8 +28,6 @@ class CuraResource(ConanFile):
             self.version = self.conan_data["version"]
 
     def export(self):
-        copy(self, pattern="conandata.yml", src=os.path.join(self.recipe_folder, ".."), dst=self.export_folder,
-             keep_path=False)
         copy(self, pattern="LICENSE*", src=os.path.join(self.recipe_folder, ".."), dst=self.export_folder,
              keep_path=False)
         update_conandata(self, {"version": self.version})

+ 38 - 0
scripts/extract_changelog.py

@@ -0,0 +1,38 @@
+import argparse
+import re
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description = 'Extract the changelog to be inserted to the release description')
+    parser.add_argument('--changelog', type = str, help = 'Path to the changelog file', required = True)
+    parser.add_argument('--version', type = str, help = 'Cura version to be extracted', required = True)
+    args = parser.parse_args()
+
+    # In the changelog we usually omit the patch number for minor release (i.e. 5.7.0 => 5.7)
+    if args.version.endswith('.0'):
+        args.version = args.version[:-2]
+
+    start_token = f"[{args.version}]"
+    pattern_stop_log = "\[\d+(\.\d+){1,2}\]"
+    log_line = False
+    first_chapter = True
+
+    with open(args.changelog, "r") as changelog_file:
+        for line in changelog_file.readlines():
+            line = line.strip()
+
+            if log_line:
+                if re.match(pattern_stop_log, line):
+                    log_line = False
+                elif len(line) > 0:
+                    if line.startswith('*'):
+                        if not first_chapter:
+                            print("")
+                        first_chapter = False
+
+                        line = line[1:].strip()
+                        print(f"<H2>{line}</H2>\n")
+                    else:
+                        print(line)
+            elif line == start_token:
+                log_line = True