Skip to content

Commit

Permalink
wip: add release-action
Browse files Browse the repository at this point in the history
  • Loading branch information
ccwienk committed Feb 5, 2025
1 parent 00745ee commit 04c135c
Showing 1 changed file with 220 additions and 0 deletions.
220 changes: 220 additions & 0 deletions .github/actions/release/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
name: release
description: |
An opinionated release-Action for creating releases adhering to conventions established within
Gardener-CICD.
This actions assumes the version to be released is contained within passed
OCM-Component-Descriptor. It also assumes a commit containing code-changes for said release was
created upfront (as output by `capture-commit` action).
Releases encompass:
- publishing of OCM Component-Descriptor
- pushing of a release-tag (pointing to release-commit)
- creating of a github-release (including release-notes + release-assets)
- pushing of "bump-commit" (to current branch)
inputs:
component-descriptor:
description: |
Effective Component-Descriptor to publish. Any local-blobs are assumed to already be
present in target-OCI-Repository.
required: true
release-commit:
description: |
release-commit in serialised form (as output by `capture-commit` action)
required: true
release-commit-target:
type: choice
description: |
controls where to push release-commit (and tag) to. Using `tag` option is safest, as it is
guaranteed to succeed, also if current branch's head change during build. As release-commit
should ideally not change (as it is referenced, e.g. in Component-Descriptor), if using
`branch` option, merging back to current branch is attempted (instead of rebase).
tag: push to tag (outside of current branch)
branch: push to current branch (attempt merge if needed)
default: tag
options:
- tag
- branch
bump-commit:
description: |
bump-commit (for setting next dev-version) in serialised form (as output by `capture-commit`
action).
required: true
release-notes:
description: |
the release-notes to publish as body for GitHub-Release (release-notes action might be
handy to collect those)
required: true
github-token:
description: |
the github-auth-token to use for authenticating against GitHub.
Use `secrets.GITHUB_TOKEN`
required: true

defaults:
run:
shell: bash

runs:
using: composite
steps:
- name: install-gardener-gha-libs
uses: gardener/cc-utils/.github/actions/install-gardener-gha-libs@master
- name: install git
run: |
if ! which git &>/dev/null; then
apt-get install git -y
fi
- uses: actions/checkout@v4
- name: import-release-commit
uses: gardener/cc-utils/.github/actions/import-commit@master
with:
commit-objects: ${{ inputs.release-commit }}
- uses: gardener/cc-utils/.github/actions/setup-git-identity@master
- name: preprocess
id: preprocess
run: |
pip install yq
# pass to next steps
echo "${{ inputs.component-descriptor }}" > /tmp/component-descriptor
version=$(yq .component.version /tmp/component-descriptor)
echo "version=${version}" >> $GITHUB_OUTPUT
tag_name="${version}"
tag_ref="refs/tags/${tag_name}"
echo "tag-ref=${tag_ref}" >> $GITHUB_OUTPUT
echo "tag-name=${tag_name}" >> $GITHUB_OUTPUT
- name: publish OCM Component-Descriptor
run: |
echo "${{ inputs.component-descriptor }}" > /tmp/component-descriptor.yaml
python -v ocm upload \
--file /tmp/component-descriptor.yaml
- name: push release-tag
run: |
set -eu
# debug (print release-commit)
echo release-commit:
orig_ref="$(git rev-parse @)"
push_spec="@:${{ steps.preprocess.outputs.tag-ref }}"
echo "pushing release-commit using ${push_spec}"
git show @
case "${{ inputs.release-commit-target }}" in
tag)
echo "chose to not push tag to source-branch: exiting now"
exit 0
;;
branch)
echo "will try to push against ${{ github.ref }}"
# fall-through (there is only error-case ahead)
;;
*)
echo "error - don't know how to handle release-commit-target:"
echo "${{ inputs.release-commit-target }}"
exit 1
;;
esac
# `branch`-case: we try to also push release-commit to branch that triggered us.
# if that fails (due to concurrent head-update), we will try to do a
# merge.
push_spec="@:${{ github.ref }}"
echo "trying to push release-commit using ${push_spec}"
if git push origin "${push_spec}"; then
echo "Successfully pushed release-commit to ${{ github.ref }}"
exit 0
fi
version="${{ steps.prepare.outputs.version }}"
echo "we failed to push release-commit to ${{ github.ref }} - trying to merge"
git fetch origin "${{ github.ref }}"
git checkout -B "${{ github.ref_name }}" FETCH_HEAD
if git merge "${orig_ref}" -m "merge back from release ${version}"; then
git push origin "@:${{ github.ref }}"
exit 0
else
echo "Warning: failed to merge release-commit back to ${{ github.ref }}"
echo "release will continue as tag was successfully pushed"
# abort merge
rm -f .git/MERGE_HEAD
git reset --hard FETCH_HEAD
git checkout -B "${{ github.ref_name }}"
# at this point, repository should have clean checkout of source-branch, pointing to
# head-commit (discarding previous failed merge-attempt + also release-commit)
# -> this should be okay:
# - tag was pushed
# - we still might succeed in publishing bump-commit
fi
- name: create github-release
shell: python
run: |
import os
import github3
import github.release
host = os.environ['GITHUB_SERVER_URL'].removeprefix('https://')
org, repo = os.environ['GITHUB_REPOSITORY'].split('/')
token = '${{ inputs.github-token }}'
if host == 'github.com':
github_api = github3.GitHub(token=token)
else:
github_api = github3.GitHubEnterprise(
url=f'https://{host}',
token=token,
)
repository = github_api.repository(org, repo)
release_notes_markdown = '''\
${{ inputs.release-notes }}
'''
release_tag_name = '${{ steps.preprocess.outputs.tag-name }}'
draft_tag_name = f'{tag_name}-draft'
if not (gh_release := github.release.find_draft_release(
repository=repository,
name=draft_tag_name,
)):
repository.create_release(
tag_name=release_tag_name,
body=release_notes_markdown or 'no release-notes available',
draft=False,
prerelease=False,
)
else:
gh_release.edit(
tag_name=release_tag_name,
name=release_tag_name,
body=release_notes_markdown or 'no release-notes available',
draft=False,
prerelease=False,
)
- name: prepare-push-bump-commit
run: |
# reset back to (current) head of branch for which release-job was started
# (this will avoid merge-conflicts)
git fetch origin "${{ github.ref }}"
git checkout -B "${{ github.ref_name }}" FETCH_HEAD
- name: import-release-commit
uses: gardener/cc-utils/.github/actions/import-commit@master
with:
commit-objects: ${{ inputs.bump-commit }}
after-import: cherry-pick

- name: prepare-push-bump-commit
run: |
git push origin "${{ github.ref }}"

0 comments on commit 04c135c

Please sign in to comment.