From cbb9daa206557c9b2a049dbf42ce349cb0d793fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Irzyk?=
 <108666440+pawelirh@users.noreply.github.com>
Date: Mon, 29 Apr 2024 14:22:46 +0200
Subject: [PATCH] Ros2 automatize release process (#272)

* Add workflows

* Update release repository workflow

* Update release project workflow

* Add pr trigger

* Change target branch

* Test pth_ros only

* On PR

* Remove PR trigger

* Add create tag step

* Change and operator

* Enable panther_msgs workflow

* Change token

* Update inputs

* Fix typo

* Add new job for retriving the date

* Add rpi-os-image things

* Add new workflow

* remove pr trigger

* Remove typo

* Create workflow

* fix typo

* Small changes in test workflow

* Fix typo

* Switch to target branch
---
 .github/workflows/release-project.yaml     | 175 +++++++++++++++++++++
 .github/workflows/release-repository.yaml  |  80 ++++++++++
 .github/workflows/test-before-release.yaml | 123 +++++++++++++++
 3 files changed, 378 insertions(+)
 create mode 100644 .github/workflows/release-project.yaml
 create mode 100644 .github/workflows/release-repository.yaml
 create mode 100644 .github/workflows/test-before-release.yaml

diff --git a/.github/workflows/release-project.yaml b/.github/workflows/release-project.yaml
new file mode 100644
index 000000000..1532042bc
--- /dev/null
+++ b/.github/workflows/release-project.yaml
@@ -0,0 +1,175 @@
+---
+name: Release Panther project
+
+on:
+    workflow_dispatch:
+        inputs:
+            target_branch:
+                description: Target branch for the release.
+                required: true
+            version:
+                description: New version (used for tag and package versioning).
+                required: true
+            release_name:
+                description: Name of the release to be created. Version in the first place is recommended (e.g. `2.0.0-alpha`).
+                required: true
+            automatic_mode:
+                type: boolean
+                default: false
+                description: Automatically merge PR and create release.
+            prerelease:
+                type: boolean
+                default: false
+                description: Mark the release as a prerelease.
+
+jobs:
+    get_date:
+        name: Get current date
+        runs-on: ubuntu-22.04
+        outputs:
+            date: ${{ steps.get_current_date.outputs.date }}
+        steps:
+            - name: Get current date
+              id: get_current_date
+              run: echo "::set-output name=date::$(date +'%Y%m%d')"
+
+    release_panther_msgs:
+        name: Release panther_msgs repository
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger repository release workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther_msgs
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: release-repository.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "target_branch": "${{ github.event.inputs.target_branch }}",
+                        "version": "${{ github.event.inputs.version }}",
+                        "release_name": "${{ github.event.inputs.release_name }}",
+                        "automatic_mode": ${{ github.event.inputs.automatic_mode }},
+                        "prerelease": ${{ github.event.inputs.prerelease }}
+                      }
+
+    release_panther_ros:
+        name: Release panther_ros repository
+        needs: release_panther_msgs
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger panther_ros release workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther_ros
+                  github_token: ${{ secrets.GITHUB_TOKEN }} # Use the default GITHUB_TOKEN for local repository
+                  workflow_file_name: release-repository.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "target_branch": "${{ github.event.inputs.target_branch }}",
+                        "version": "${{ github.event.inputs.version }}",
+                        "release_name": "${{ github.event.inputs.release_name }}",
+                        "automatic_mode": ${{ github.event.inputs.automatic_mode }},
+                        "prerelease": ${{ github.event.inputs.prerelease }}
+                      }
+
+    release_panther_docker:
+        name: Release panther-docker repository
+        needs:
+            - release_panther_ros
+            - get_date
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger repository release workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther-docker
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: release-repository.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "target_branch": "${{ github.event.inputs.target_branch }}",
+                        "version": "${{ github.event.inputs.version }}",
+                        "date": "${{ needs.get_date.outputs.date }}",
+                        "release_name": "${{ github.event.inputs.release_name }}",
+                        "automatic_mode": ${{ github.event.inputs.automatic_mode }},
+                        "prerelease": ${{ github.event.inputs.prerelease }}
+                      }
+
+    build_and_push_docker_images:
+        name: Build panther docker images
+        needs:
+            - release_panther_docker
+            - get_date
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger repository build workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther-docker
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: ros-docker-image.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "build_type": "stable",
+                        "target_distro": "humble",
+                        "target_release": "${{ github.event.inputs.version }}",
+                        "target_date": "${{ needs.get_date.outputs.date }}"
+                      }
+
+    release_panther_rpi_os_image:
+        name: Release panther-rpi-os-image repository
+        needs:
+            - release_panther_docker
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger repository release workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther-rpi-os-image
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: release-repository.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "target_branch": "${{ github.event.inputs.target_branch }}",
+                        "version": "${{ github.event.inputs.version }}",
+                        "release_name": "${{ github.event.inputs.release_name }}",
+                        "automatic_mode": ${{ github.event.inputs.automatic_mode }},
+                        "prerelease": ${{ github.event.inputs.prerelease }}
+                      }
+
+    build_and_publish_rpi_image:
+        name: Build panther docker images
+        needs:
+            - release_panther_rpi_os_image
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger repository build workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther-rpi-os-image
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: build_and_deploy_image.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "dev_image": "false",
+                        "panther_codebase_version": "${{ github.event.inputs.version }}",
+                        "image_tag": "${{ github.event.inputs.release_name }}",
+                      }
diff --git a/.github/workflows/release-repository.yaml b/.github/workflows/release-repository.yaml
new file mode 100644
index 000000000..5262906fe
--- /dev/null
+++ b/.github/workflows/release-repository.yaml
@@ -0,0 +1,80 @@
+---
+name: Release repository
+
+on:
+    workflow_dispatch:
+        inputs:
+            target_branch:
+                description: Target branch for the release.
+                required: true
+            version:
+                description: New version (used for tag and package versioning).
+                required: true
+            release_name:
+                description: Name of the release to be created. Version in the first place is recommended (e.g. `2.0.0-alpha`).
+                required: true
+            automatic_mode:
+                type: boolean
+                default: false
+                description: Automatically merge PR and create release.
+            prerelease:
+                type: boolean
+                default: false
+                description: Mark the release as a prerelease.
+
+jobs:
+    release:
+        name: Release repository
+        runs-on: ubuntu-22.04
+        env:
+            GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        steps:
+            - name: Checkout
+              uses: actions/checkout@v4
+              with:
+                  ref: ${{ github.event.inputs.target_branch }}
+
+            - name: Create release candidate
+              id: create_release_candidate
+              uses: at-wat/catkin-release-action@v1
+              with:
+                  version: ${{ github.event.inputs.version }}
+                  git_user: action-bot
+                  git_email: action-bot@action-bot.com
+                  github_token: ${{ secrets.GITHUB_TOKEN }}
+
+            - name: Create pull request
+              run: |
+                  gh pr create \
+                  --base ${{ github.event.inputs.target_branch }} \
+                  --head ${{ steps.create_release_candidate.outputs.created_branch }} \
+                  --title "Release ${{ steps.create_release_candidate.outputs.version}}" \
+                  --body "This PR incorporates package(s) version and changelog update."
+
+            - name: Merge pull request
+              if: ${{ github.event.inputs.automatic_mode == true }}
+              run: |
+                  gh pr merge ${{ steps.create_release_candidate.outputs.created_branch }} \
+                  --delete-branch
+
+            - name: Create tag
+              if: ${{ github.event.inputs.automatic_mode == true }}
+              run: |
+                  git checkout ${{ github.event.inputs.target_branch }}
+                  git tag ${{ steps.create_release_candidate.outputs.version }}
+                  git push origin ${{ steps.create_release_candidate.outputs.version }}
+
+            - name: Create prerelease
+              if: ${{ github.event.inputs.automatic_mode == true && github.event.inputs.prerelease == true}}
+              run: |
+                  gh release create ${{ steps.create_release_candidate.outputs.version }} \
+                  --title ${{ github.event.inputs.release_name }} \
+                  --notes-from-tag \
+                  --prerelease
+
+            - name: Create release
+              if: ${{ github.event.inputs.automatic_mode == true && github.event.inputs.prerelease == false}}
+              run: |
+                  gh release create ${{ steps.create_release_candidate.outputs.version }} \
+                  --title ${{ github.event.inputs.release_name }} \
+                  --notes-from-tag
diff --git a/.github/workflows/test-before-release.yaml b/.github/workflows/test-before-release.yaml
new file mode 100644
index 000000000..dd16cd730
--- /dev/null
+++ b/.github/workflows/test-before-release.yaml
@@ -0,0 +1,123 @@
+---
+name: Test before release
+
+on:
+    workflow_dispatch:
+        inputs:
+            target_branch:
+                description: Target branch for the release.
+                required: true
+            test_tag:
+                description: Test tag name (used for images tagging).
+                required: true
+
+jobs:
+    # TODO: Add unit testing for panther_ros when ready
+    unit_test_panther_ros:
+        name: Run unit tests for panther_ros
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger repository build workflow
+              run: echo "Unit tests for panther_ros are not fully implemented yet -> SKIPPING!"
+
+    prepare_test_branches_ros:
+        name: Prepare test branch for ROS repositories
+        runs-on: ubuntu-22.04
+        needs:
+            - unit_test_panther_ros
+        strategy:
+            matrix:
+                repo: [panther_ros, panther_msgs]
+        steps:
+            - name: Create test branch
+              uses: GuillaumeFalourd/create-other-repo-branch-action@v1.5
+              with:
+                  repository_owner: husarion
+                  repository_name: ${{ matrix.repo }}
+                  new_branch_name: ${{ github.event.inputs.test_tag }}
+                  new_branch_ref: ${{ github.event.inputs.target_branch }}
+                  access_token: ${{ secrets.GH_PAT}}
+
+    prepare_test_branch_docker:
+        name: Prepare branch with test compose
+        runs-on: ubuntu-22.04
+        needs:
+            - unit_test_panther_ros
+        steps:
+            - name: Trigger repository build workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther-docker
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: prepare-test-branch.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "target_branch": "${{ github.event.inputs.target_branch }}",
+                        "test_branch": "${{ github.event.inputs.test_tag }}"
+                      }
+
+    build_and_push_docker_images:
+        name: Build panther docker images
+        runs-on: ubuntu-22.04
+        needs:
+            - prepare_test_branch_docker
+        steps:
+            - name: Trigger repository build workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther-docker
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: ros-docker-image.yaml
+                  ref: ${{ github.event.inputs.test_tag }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "build_type": "development",
+                        "target_distro": "humble"
+                      }
+
+    build_and_publish_rpi_image:
+        name: Build panther system image
+        needs:
+            - prepare_test_branches_ros
+            - prepare_test_branch_docker
+        runs-on: ubuntu-22.04
+        steps:
+            - name: Trigger repository build workflow
+              uses: convictional/trigger-workflow-and-wait@v1.6.1
+              with:
+                  owner: husarion
+                  repo: panther-rpi-os-img
+                  github_token: ${{ secrets.GH_PAT }}
+                  workflow_file_name: build_and_deploy_image.yaml
+                  ref: ${{ github.event.inputs.target_branch }}
+                  wait_interval: 10
+                  client_payload: |
+                      {
+                        "dev_image": "true",
+                        "panther_codebase_version": "${{ github.event.inputs.test_tag }}",
+                        "image_tag": "${{ github.event.inputs.test_tag }}"
+                      }
+
+    delete_test_branches:
+        name: Delete test branches
+        runs-on: ubuntu-22.04
+        needs:
+            - build_and_push_docker_images
+            - build_and_publish_rpi_image
+        if: always() # Always delete test branches, even if previous jobs failed
+        strategy:
+            matrix:
+                repo: [panther_ros, panther_msgs, panther-docker]
+        steps:
+            - name: Delete test branch
+              uses: dawidd6/action-delete-branch@v3
+              with:
+                  owner: husarion
+                  repository: ${{ matrix.repo }}
+                  branches: ${{ github.event.inputs.test_tag }}
+                  github_token: ${{ secrets.GH_PAT}}