Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ci): rework release workflow and communications #1184

Merged
merged 2 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 167 additions & 39 deletions .github/actions/release/action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: "tag version"
description: "Tag package"
name: "release action"
description: "Create git release tags, github releases, jira version and push release communication."
inputs:
github_ref_name:
description: "Github ref name"
required: true
jira_api_token:
description: "Token to authenticate to Jira"
required: true
Expand All @@ -10,57 +13,182 @@ inputs:
jira_project_id:
description: "Jira project id to create release"
required: true
jira_base_url:
description: "Jira base url"
jira_webhook_url:
description: "Jira release webhook"
required: true

runs:
using: "composite"
steps:
- name: Publish RPMS to Repositories
- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Get released versions for components
run: |
NEW_VERSION=""
MAJOR_VERSION=$(echo $GITHUB_REF_NAME | grep -oP '([0-9]{2}\.[0-9]{2})')
echo "Major version: $MAJOR_VERSION"
HOTFIX=$(echo $GITHUB_REF_NAME | grep -oP '(hotfix|)')
echo "Hotfix: $HOTFIX"
BETA=$(echo $GITHUB_REF_NAME | grep -oP '(beta|)')
echo "Beta: $BETA"
RELEASE_ID=$(git log -1 --pretty=%B | grep -oP '(#[0-9]{4,}#)' | grep -oP '([0-9]+)')
echo "Release Id: $RELEASE_ID"

OLDV=$(git tag --sort=-v:refname --list "centreon-collect-$MAJOR_VERSION.*" | head -n 1)
echo "Old version: $OLDV"
set -eu

# Variables
COMPONENTS_COLLECT=("centreon-collect")
CURRENT_STABLE_BRANCH_MAJOR_VERSION=""
declare -a NEW_STABLE_TAGS=()
declare -a PREVIOUS_STABLE_TAGS=()
SCOPE_VERSION="COLLECT"
MINOR_VERSION_FILE_PATH=".version"

# Get current stable branch name
CURRENT_STABLE_BRANCH_MAJOR_VERSION=$(echo ${{ inputs.github_ref_name }} | cut -d '.' -f1,2)
echo "Current stable branch major version: $CURRENT_STABLE_BRANCH_MAJOR_VERSION"

# Get previous and new version tags for components
for component in ${COMPONENTS_COLLECT[@]}; do
if [[ $component == "centreon-web" ]]; then
COMPONENT_DIR="centreon"
else
COMPONENT_DIR=$component
fi
MAJOR_VERSION=$(grep -E "MAJOR" .version | cut -d '=' -f2)
MINOR_VERSION=$(grep -E "MINOR" .version | cut -d '=' -f2)
# Previous stable tags array
PREVIOUS_STABLE_TAGS+=($(git tag -l --sort=-version:refname "$component-$CURRENT_STABLE_BRANCH_MAJOR_VERSION*" | head -n 1))
# New stable tags array
NEW_STABLE_TAGS+=("$component-$MAJOR_VERSION.$MINOR_VERSION")
done
echo "Previous releases were: ${PREVIOUS_STABLE_TAGS[*]}"
echo "New releases are: ${NEW_STABLE_TAGS[*]}"

# TODO: Check that NEW_STABLE_TAGS are fully different from PREVIOUS_STABLE_TAGS
# re use the part from check version ??
# or use the check-version action after turning this release action into a real workflow ?

# Make NEW_STABLE_TAGS available for other steps
echo "NEW_STABLE_TAGS=${NEW_STABLE_TAGS[*]}" >> "$GITHUB_ENV"
echo "CURRENT_STABLE_BRANCH_MAJOR_VERSION=$CURRENT_STABLE_BRANCH_MAJOR_VERSION" >> "$GITHUB_ENV"
echo "SCOPE_VERSION=$SCOPE_VERSION" >> "$GITHUB_ENV"
shell: bash

- name: Add new release tags to stable branch
run: |
# Add new stable tags to stable branch
echo "Configuring git."
git config --global user.email "[email protected]"
git config --global user.name "Centreon"

if [ -z "$OLDV" ]; then
echo "No existing version, starting at $MAJOR_VERSION.0"
NEW_VERSION="$MAJOR_VERSION.0"
git tag -a "centreon-collect-$NEW_VERSION" -m "version $NEW_VERSION"
git push --follow-tags
else
OLD_MINOR_VERSION=$(echo $OLDV | grep -oP '([0-9]+$)')
NEW_MINOR_VERSION=$(echo $((OLD_MINOR_VERSION + 1)))
NEW_VERSION=$MAJOR_VERSION.$NEW_MINOR_VERSION
git tag -a "centreon-collect-$NEW_VERSION" -m "version $NEW_VERSION"
git push --follow-tags
fi
# Create release tags on git for each release components
echo "Creating release tags."
for TAG in ${NEW_STABLE_TAGS[@]}; do
if [ -z $(git tag --list "$TAG" | head -n 1) ]; then
git tag -a "$TAG" -m "$TAG"
git push --follow-tags
echo "::notice::Tagging stable branch with $TAG."
else
echo "::error::Release tag $TAG already exists, exiting."
exit 1
fi
done
shell: bash

if [ "$HOTFIX" == "hotfix" ]; then
TYPE=Hotfix
- name: Create GITHUB releases from new release tags
run: |
# Install gh cli
echo "Installing GH CLI."
if ! command -v gh &> /dev/null; then
echo "Installing GH CLI."
type -p curl >/dev/null || (sudo apt-get update && sudo apt-get install curl -y)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt-get update
sudo apt-get install gh -y
else
TYPE=Release
echo "GH CLI is already installed."
fi

VERSION_DATA="{\"archived\":false,\"releaseDate\":\"$(date +%Y-%m-%d)\",\"name\":\"centreon-collect-$NEW_VERSION\",\"description\":\"$TYPE:$RELEASE_ID\",\"projectId\":${{ inputs.jira_project_id }},\"released\":false}"
# Create GITHUB release for each release components
echo "Creating GITHUB releases."
for TAG in ${NEW_STABLE_TAGS[@]}; do
echo "Creating GITHUB release with title $TAG for tag $TAG."
gh release create $TAG --target "${{ inputs.github_ref_name }} --title "$TAG" --verify-tag
done
shell: bash

- name: Create stable JIRA versions from new release tags
run: |
set -eu

# Call JIRA to provide new jira versions to create
# Webhook url
JIRA_INCOMING_WEBHOOK="${{ inputs.jira_webhook_url }}"

# Rebuild NEW_STABLE_TAGS as an array
for i in ${NEW_STABLE_TAGS[@]}; do
NEW_RELEASE_TAGS+=("$i")
done

# Create new JIRA versions (old way of doing it)
# TODO: add a future capacity to determine wether the release is hotfix or standard (using TYPE)
# OR: rely on jira automation to do it (less hassle on github side, and jira knows jira best)

# Build JSON vars for JIRA_RELEASE_DATA
JIRA_RELEASE_ARCHIVED="false"
JIRA_RELEASE_DESCRIPTION=""
JIRA_RELEASE_DATE="$(date +%Y-%m-%d)"
JIRA_RELEASE_NAME=""
JIRA_PROJECT_ID="${{ inputs.jira_project_id }}"
JIRA_RELEASE_RELEASED="false"

# Create JIRA version for each released component
echo "Creating JIRA releases."
for TAG in ${NEW_RELEASE_TAGS[@]}; do
echo "::notice::Creating JIRA release $TAG based on git release tag $TAG."
# Build JSON with release information for JIRA API
JIRA_RELEASE_DATA=$(jq -nc \
--arg archived "$JIRA_RELEASE_ARCHIVED" \
--arg description "$TAG" \
--arg releaseDate "$JIRA_RELEASE_DATE" \
--arg name "$TAG" \
--arg projectId "$JIRA_PROJECT_ID" \
--arg released "$JIRA_RELEASE_RELEASED" \
'$ARGS.named' )
# Send to JIRA API release
echo "Sending to JIRA API release: $JIRA_RELEASE_DATA"
curl --fail --request POST \
--url 'https://centreon.atlassian.net/rest/api/3/version' \
--user '${{ inputs.jira_user_email }}:${{ inputs.jira_api_token }}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data "$JIRA_RELEASE_DATA"
done
shell: bash

- name: Trigger release communication for new releases
run: |
set -eu
MAJOR_VERSION=$CURRENT_STABLE_BRANCH_MAJOR_VERSION

# Webhook url
JIRA_INCOMING_WEBHOOK="${{ inputs.jira_webhook_url }}"

# Rebuild NEW_STABLE_TAGS as an array
for i in ${NEW_STABLE_TAGS[@]}; do
NEW_RELEASE_TAGS+=("$i")
done

# Build JSON structure with released versions
JSON_TAGS=$(jq -n '{componentList:$ARGS.positional}' --args "${NEW_RELEASE_TAGS[@]}")
JSON_VERSION_INFO=$(jq -n --arg majorVersion "$MAJOR_VERSION" --arg scopeVersion "$SCOPE_VERSION" '$ARGS.named' )
RELEASE_JSON=$(echo "$JSON_VERSION_INFO" | jq -c --argjson json_tags "$JSON_TAGS" '. += $json_tags')

# DEBUG
echo "JSON_TAGS: \r\n$JSON_TAGS"
echo "JSON_VERSION_INFO: $JSON_VERSION_INFO"
echo "Sending to JIRA automation: \r\n$RELEASE_JSON"

curl --fail --request POST \
--url '${{ inputs.jira_base_url }}/rest/api/3/version' \
--user '${{ inputs.jira_user_email }}:${{ inputs.jira_api_token }}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data ''$VERSION_DATA''
# Call jira webhook to trigger the communication workflow
# and provide versions data for communication
curl \
"$JIRA_INCOMING_WEBHOOK" \
-X POST \
-H 'Content-type: application/json' \
--data "$RELEASE_JSON"

shell: bash
37 changes: 0 additions & 37 deletions .github/workflows/release-collect.yml

This file was deleted.

52 changes: 52 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: Release

on:
pull_request:
types:
- closed
branches:
- master
- "[2-9][0-9].[0-9][0-9].x"
paths-ignore:
- ".github/**"
- ".jira/**"
- "tests/**"
- ".deepsource.toml"
- ".veracode-exclusions"
- "README.md"
- "sonar-project.properties"
workflow_dispatch:

jobs:
release:
if: ${{ github.event.pull_request.merged == true }}
runs-on: ubuntu-22.04
steps:
- name: Check base_ref
run: |
set -eu
# Check if github.base_ref is either master or any of the supported version ones
# This must never run on any other than master and supported version base_ref
if [[ "${{ github.base_ref }}" == 'master' || "${{ github.base_ref }}" =~ ^[2-9][0-9].[0-9][0-9].x ]];then
echo "[DEBUG] base_ref is valid: ${{ github.base_ref }}"
else
echo "::error::base_ref is not valid (${{ github.base_ref }}), exiting."
exit 1
fi
shell: bash

- name: Checkout sources
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0

- name: Release
id: release
uses: ./.github/actions/release
with:
github_ref_name: ${{ github.head_ref || github.ref_name }}
jira_project_id: ${{ secrets.JIRA_PROJECT_ID }}
jira_user_email: ${{ secrets.XRAY_JIRA_USER_EMAIL }}
jira_api_token: ${{ secrets.XRAY_JIRA_TOKEN }}
jira_webhook_url: ${{ secrets.JIRA_RELEASE_WEBHOOK }}