Skip to content

GrimoireLab release #163

GrimoireLab release

GrimoireLab release #163

# Basic workflow to release GrimoireLab 2.x-alpha releases
# For this workflow all the versions are prereleases
name: GrimoireLab release
on:
workflow_dispatch:
inputs:
prerelease:
description: "Create a pre-release version"
required: true
type: boolean
default: false
prerelease_label:
description: "Label for pre-release"
required: false
type: choice
options:
- alpha
- beta
- rc
default: rc
bump_major:
description: "Create a major version release"
required: true
type: boolean
default: false
git_email:
description: "Git email for commits messages"
required: true
default: "[email protected]"
git_name:
description: "Git name for commits messages"
required: true
default: "Santiago Dueñas"
jobs:
variables-job:
name: Set variables
runs-on: ubuntu-latest
outputs:
git_email: ${{ steps.variables.outputs.git_email }}
git_name: ${{ steps.variables.outputs.git_name }}
prerelease: ${{ steps.variables.outputs.prerelease }}
prerelease_label: ${{ inputs.prerelease_label }}
bump_major: ${{ steps.variables.outputs.bump_major }}
steps:
- id: variables
name: variables
run: |
echo "git_email=${{ inputs.git_email }}" >> $GITHUB_OUTPUT
echo "git_name=${{ inputs.git_name }}" >> $GITHUB_OUTPUT
echo "prerelease=${{ inputs.prerelease }}" >> $GITHUB_OUTPUT
echo "prerelease_label=${{ inputs.prerelease_label }}" >> $GITHUB_OUTPUT
echo "bump_major=${{ inputs.bump_major }}" >> $GITHUB_OUTPUT
grimoirelab-chronicler:
name: chronicler
needs:
- variables-job
uses: ./.github/workflows/release-grimoirelab-component.yml
with:
git_email: ${{ needs.variables-job.outputs.git_email }}
git_name: ${{ needs.variables-job.outputs.git_name }}
prerelease: ${{ needs.variables-job.outputs.prerelease }}
prerelease_label: ${{ needs.variables-job.outputs.prerelease_label }}
bump_major: ${{ needs.variables-job.outputs.bump_major }}
module_name: 'grimoirelab-chronicler'
module_repository: 'grimoirelab/grimoirelab-chronicler'
module_directory: 'src/grimoirelab-chronicler'
dependencies: ''
secrets:
access_token: ${{ secrets.GRIMOIRELAB_BUILD_TOKEN }}
grimoirelab-core:
name: GrimoireLab Core
needs:
- variables-job
- grimoirelab-chronicler
uses: ./.github/workflows/release-grimoirelab-component.yml
with:
git_email: ${{ needs.variables-job.outputs.git_email }}
git_name: ${{ needs.variables-job.outputs.git_name }}
prerelease: ${{ needs.variables-job.outputs.prerelease }}
prerelease_label: ${{ needs.variables-job.outputs.prerelease_label }}
bump_major: ${{ needs.variables-job.outputs.bump_major }}
module_name: 'grimoirelab-core'
module_repository: 'grimoirelab/grimoirelab-core'
module_directory: 'src/grimoirelab-core'
dependencies: "${{ needs.grimoirelab-chronicler.outputs.package_version }}"
secrets:
access_token: ${{ secrets.GRIMOIRELAB_BUILD_TOKEN }}
grimoirelab:
name: Grimoirelab
runs-on: ubuntu-latest
environment: grimoire-release
needs:
- variables-job
- grimoirelab-chronicler
- grimoirelab-core
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
token: '${{ secrets.GRIMOIRELAB_BUILD_TOKEN }}'
- name: Set up Python 3.12
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
with:
python-version: 3.12
- name: Set up Git config
run: |
git config --global user.email "${{ inputs.git_email }}"
git config --global user.name "${{ inputs.git_name }}"
- name: Install poetry
run: |
pipx install poetry
- name: Install release-tools
#TODO: Change to the latest version once the new release is created
run: pip install git+https://github.com/Bitergia/release-tools.git#egg=release-tools
- id: check-dependencies
name: Check if package dependencies exist
run: |
sleep 180
- id: semverup
name: Update version number
env:
chronicler_version: "${{ needs.grimoirelab-chronicler.outputs.version}}"
grimoirelab_core_version: "${{ needs.grimoirelab-core.outputs.version}}"
run: |
BUMP_MAJOR=4
BUMP_MINOR=2
BUMP_PATCH=1
NO_BUMP=0
function cmp_version () {
old=$1
old=${old%-*}
old=${old%rc*}
current=$2
current=${current%-*}
current=${current%rc*}
currentArr=(${current//./ })
oldArr=(${old//./ })
if [ ${currentArr[0]} -gt ${oldArr[0]} ]
then
echo $BUMP_MAJOR
elif [ ${currentArr[1]} -gt ${oldArr[1]} ]
then
echo $BUMP_MINOR
elif [ ${currentArr[2]} -gt ${oldArr[2]} ]
then
echo $BUMP_PATCH
else
echo $NO_BUMP
fi
}
function old_pkg_version () {
pkg=$1
poetry show -l $pkg | grep version | head -1 | awk '{print $3}'
}
pkgs=("chronicler"
"grimoirelab-core")
if [ ${{ inputs.prerelease }} == 'true' ]
then
rcArg='--pre-release --pre-release-label=${{ inputs.prerelease_label }}'
else
rcArg=''
fi
versionUpdated=0
for pkg in "${pkgs[@]}"
do
pkg_ver="${pkg/-/_}_version"
current=${!pkg_ver}
old=$(old_pkg_version "$pkg")
output=$(cmp_version "$old" "$current")
echo "$pkg updated from $old to $current, changed: $output"
versionUpdated=$(( versionUpdated | output ))
done
echo $versionUpdated
if [ ${{ inputs.bump_major }} == 'true' ]
then
version=$(semverup --bump-version=major $rcArg)
elif [ $((versionUpdated & $BUMP_MAJOR )) -ne 0 ]
then
version=$(semverup --bump-version=major $rcArg)
elif [ $((versionUpdated & $BUMP_MINOR )) -ne 0 ]
then
version=$(semverup --bump-version=minor $rcArg)
else
version=$(semverup --bump-version=patch $rcArg)
fi
echo $version
git add pyproject.toml grimoirelab/_version.py
echo "version=$version" >> $GITHUB_OUTPUT
- name: Update dependencies files
run: |
poetry add --lock --allow-prereleases \
"${{ needs.grimoirelab-chronicler.outputs.package_version }}" \
"${{ needs.grimoirelab-core.outputs.package_version }}"
poetry update --lock
git add pyproject.toml
git add poetry.lock
- name: Use custom release notes if exists
id: custom_notes
run: |
version=${{ steps.semverup.outputs.version }}
custom_file=releases/custom_release_notes.md
release_file=releases/$version.md
news_file="NEWS"
old_news="NEWS_old"
if [ -e $custom_file ]
then
echo "Using custom release file"
# News file
if [ ${{ inputs.prerelease }} == 'false' ]
then
mv $news_file $old_news
touch $news_file
echo "# Releases" >> $news_file
echo "" >> $news_file
cat $custom_file >> $news_file
echo "" >> $news_file
cat $old_news | tail -n +2 >> $news_file
fi
# Release file
git mv $custom_file $release_file
echo "custom_notes=true" >> $GITHUB_OUTPUT
else
echo "Using packages release notes"
echo "custom_notes=false" >> $GITHUB_OUTPUT
fi
- name: Generate release notes from packages
if: steps.custom_notes.outputs.custom_notes == 'false'
env:
grimoirelab_chronicler_notes: "${{ needs.grimoirelab-chronicler.outputs.notes}}"
grimoirelab_core_notes: "${{ needs.grimoirelab-core.outputs.notes}}"
run: |
version=${{ steps.semverup.outputs.version }}
release_file=releases/$version.md
eof="EOF$(date +%s)"
touch $release_file
cat << $eof > $release_file
# GrimoireLab $version
The following list describes the changes by component:
$grimoirelab_chronicler_notes
$grimoirelab_core_notes
$eof
cat $release_file
- name: Generate NEWS from packages
if: steps.custom_notes.outputs.custom_notes == 'false'
env:
notes_chronicler: "${{ needs.grimoirelab-chronicler.outputs.notes}}"
notes_grimoirelab_core: "${{ needs.grimoirelab-core.outputs.notes}}"
version_chronicler: "${{ needs.grimoirelab-chronicler.outputs.version }}"
version_grimoirelab_core: "${{ needs.grimoirelab-core.outputs.version }}"
run: |
version=${{ steps.semverup.outputs.version }}
news_file="NEWS"
old_news="NEWS_old"
new_notes="tmp_new_notes"
today=$(date -u "+%Y-%m-%d")
packages=(
chronicler
grimoirelab_core
)
mv $news_file $old_news
touch $news_file $new_notes
echo "# Releases" >> $news_file
echo "" >> $news_file
echo "## GrimoireLab $version - ($today)" >> $news_file
echo "" >> $news_file
echo "**New components:**" >> $news_file
echo "" >> $news_file
for package in "${packages[@]}"
do
package_name=$(echo $package | tr '_' '-')
package_version_var="version_$package"
package_notes_var="notes_$package"
package_version="${!package_version_var}"
package_notes="${!package_notes_var}"
contents="$(echo "$package_notes" | tail -n +2)"
if [ ! -z "$contents" ]
then
echo "* $package_name $package_version" >> $news_file
echo "### $package_name" >> $new_notes
echo "$contents" >> $new_notes
echo "" >> $new_notes
fi
done
echo "" >> $news_file
echo "The following list describes the changes by component:" >> $news_file
echo "" >> $news_file
cat $new_notes >> $news_file
cat $old_news | tail -n +2 >> $news_file
rm $old_news $new_notes
git add $news_file
cat $news_file
- name: Update Dockerfile version
# if: inputs.prerelease == false
run: |
version=${{ steps.semverup.outputs.version }}
dockerfile="docker/Dockerfile"
sed -i "s/ARG GRIMOIRELAB_RELEASE=.*/ARG GRIMOIRELAB_RELEASE=\"$version\"/" $dockerfile
git add $dockerfile
cat $dockerfile
- id: update_submodules
name: Update Git submodule repositories
run: |
git submodule update --init --remote
git add src/
- id: current_time
name: Store current time to get the release workflow
if: steps.semverup.outcome == 'success'
run: |
datetime=$(date +"%Y-%m-%dT%H:%M:%S%z")
echo "datetime=$datetime" >> $GITHUB_OUTPUT
echo $datetime
- id: publish
name: Publish new version.
if: steps.semverup.outcome == 'success'
run: |
if [ ${{ inputs.prerelease }} == 'true' ]
then
publish ${{ steps.semverup.outputs.version }} "${{ inputs.git_name }} <${{ inputs.git_email }}>" \
--push origin --remote-branch ${GITHUB_REF#refs/heads/} --no-cleanup
else
publish ${{ steps.semverup.outputs.version }} "${{ inputs.git_name }} <${{ inputs.git_email }}>" \
--push origin --remote-branch ${GITHUB_REF#refs/heads/}
fi
- id: wait-for-release
name: Wait for release to finish.
if: steps.publish.outcome == 'success'
run: |
url="https://api.github.com/repos/chaoss/grimoirelab/actions/workflows/release.yml/runs?created=>${{ steps.current_time.outputs.datetime }}"
while true
do
workflows=$(curl -sS -H "Authorization: token ${{ secrets.GRIMOIRELAB_BUILD_TOKEN }}" $url)
if [ $(echo $workflows | jq '.total_count') -eq 0 ]
then
echo "Release workflow did not start"
sleep 60
continue
fi
release_conclusion=$(echo $workflows | jq '.workflow_runs[0].conclusion')
release_status=$(echo $workflows | jq '.workflow_runs[0].status')
if [ $release_status = \"completed\" -a $release_conclusion = \"success\" ]
then
echo "Release completed!";
break;
elif [ $release_status = \"completed\" -a $release_conclusion != \"success\" ]
then
echo "Release failed!";
exit 1;
else
echo $release_conclusion $release_status
echo "Waiting for release..."
sleep 60
fi
done
- id: rollback
name: Rollback last commits and remove tag
if: steps.wait-for-release.outcome == 'failure'
run: |
git reset --hard HEAD~1
git push -f origin ${GITHUB_REF#refs/heads/}
git tag -d ${{ steps.semverup.outputs.version }}
git push --delete origin ${{ steps.semverup.outputs.version }}
# Force to fail
exit 1
working-directory: ${{ inputs.module_directory }}