GrimoireLab release #163
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 }} |