-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
51f47a8
commit 48276d4
Showing
3 changed files
with
213 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
name: Auto-tag | ||
on: | ||
push: | ||
tags: | ||
- '*.*.*' | ||
jobs: | ||
auto-tag: | ||
name: Auto-tag | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Auto-tag | ||
uses: silverstripe/gha-auto-tag@main |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,32 @@ | ||
# gha-tag-release | ||
# GitHub Actions - Tag release | ||
|
||
Create a tag and an optional release | ||
|
||
## Usage | ||
|
||
**workflow.yml** | ||
```yml | ||
steps: | ||
- name: Create tag and release | ||
uses: silverstripe/gha-pull-request@main | ||
with: | ||
tag: 1.2.3 | ||
release: true | ||
``` | ||
Read more information about the inputs available for [silverstripe/gha-pull-request](https://github.com/silverstripe/gha-pull-request). | ||
## Why there is no SHA input paramater | ||
Creating a tag for a particular SHA, either via the GitHub API or via CLI (i.e. git tag) in an action is strangely blocked. The error is "Resource not accessible by integration" which is a permissions error. | ||
However, tags can be created with the following methods: | ||
- Using `${{ github.sha }}` which is the latest sha in a context instead of historic sha | ||
- Creating a release via GitHub API, which will also create a tag. While it's tempting to just use this and then delete the release, it's seems possible that this may stop working in the future | ||
|
||
The following methods have been attempted: | ||
- Using third party actions to create tags | ||
- Passing in `permissions: write-all` from the calling workflow | ||
- Passing in a github token from the calling workflow | ||
|
||
It's likely that `${{ github.sha }}` will be good enough though - the intention is that this action will be used to tag the _most recent commit_ on a given branch, e.g. after a pull request is merged. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
name: Tag and release | ||
description: GitHub Action to create a tag and an optional release | ||
|
||
inputs: | ||
# Note: there is an explicit reason why there is no sha input parameter - see the readme | ||
tag: | ||
type: string | ||
required: true | ||
delete_existing: | ||
type: boolean | ||
required: false | ||
default: false | ||
release: | ||
type: boolean | ||
required: false | ||
default: false | ||
release_description: | ||
type: string | ||
required: false | ||
default: '' | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
|
||
- name: Validate inputs | ||
shell: bash | ||
env: | ||
TAG: ${{ inputs.tag }} | ||
run: | | ||
git check-ref-format "tags/$TAG" > /dev/null | ||
if [[ $? != "0" ]]; then | ||
echo "Invalid tag" | ||
exit 1 | ||
fi | ||
- name: Delete existing release if one exists | ||
if: ${{ inputs.release == 'true' && inputs.delete_existing == 'true' }} | ||
shell: bash | ||
env: | ||
TAG: ${{ inputs.tag }} | ||
GITHUB_REPOSITORY: ${{ github.repository }} | ||
run: | | ||
# Get id for an existing release matching $TAG | ||
# https://docs.github.com/en/rest/releases/releases#get-a-release-by-tag-name | ||
RESP_CODE=$(curl -w %{http_code} -s -o __response.json \ | ||
-X GET https://api.github.com/repos/$GITHUB_REPOSITORY/releases/tags/$TAG \ | ||
-H "Accept: application/vnd.github.v3+json") | ||
if [[ $RESP_CODE != "200" ]]; | ||
echo "Unable to check tag status for $TAG - HTTP response code was $RESP_CODE" | ||
exit 1 | ||
fi | ||
RELEASE_ID=$https://docs.github.com/en/rest/git/refs#get-a-reference(jq .id __response.json) | ||
if [[ $RELEASE_ID == "null" ]]; then | ||
echo "Did not find an existing release for tag $TAG" | ||
else | ||
# https://docs.github.com/en/rest/releases/releases#delete-a-release | ||
RESP_CODE=$(curl -w %{http_code} -s -o /dev/null \ | ||
-X DELETE https://api.github.com/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token ${{ github.token }}" | ||
if [[ $RESP_CODE != "204" ]]; | ||
echo "Unable to delete release $RELEASE_ID for tag $TAG - HTTP response code was $RESP_CODE" | ||
exit 1 | ||
fi | ||
echo "Deleted existing release $RELEASE_ID for tag $TAG" | ||
fi | ||
- name: Delete existing tag if one exists | ||
if: ${{ inputs.delete_existing == 'true' }} | ||
shell: bash | ||
env: | ||
TAG: ${{ inputs.tag }} | ||
GITHUB_REPOSITORY: ${{ github.repository }} | ||
run: | | ||
# Check if tag currently exists | ||
# Note: not using https://api.github.com/repos/$GITHUB_REPOSITORY/git/refs/tags/<tag> | ||
# because that uses a "starts-with" filter, so it will also match -beta1 and -rc1 tags | ||
# https://docs.github.com/en/rest/git/refs#get-a-reference | ||
RESP_CODE=$(curl -w %{http_code} -s -o __response.json \ | ||
-X GET https://api.github.com/repos/$GITHUB_REPOSITORY/git/refs/tags \ | ||
-H "Accept: application/vnd.github.v3+json") | ||
if [[ $RESP_CODE != "200" ]]; | ||
echo "Unable to check tag status - HTTP response code was $RESP_CODE" | ||
exit 1 | ||
fi | ||
FOUND="true" | ||
# Check there are any tags so we can use jq array selector later | ||
if [[ $(jq 'map(type)' __response.json) =~ object ]]; then | ||
if [[ $(jq '.[] | select(.ref == "refs/tags/$TAG")' __response.json) == "" ]]; then | ||
FOUND="false" | ||
fi | ||
fi | ||
if [[ $FOUND == "false" ]]; then | ||
echo "Did not find an existing tag for $TAG" | ||
else | ||
# Delete tag via GitHub API | ||
# https://docs.github.com/en/rest/reference/git#delete-a-reference | ||
RESP_CODE=$(curl -w %{http_code} -s -o /dev/null \ | ||
curl -s \ | ||
-X DELETE https://api.github.com/repos/$GITHUB_REPOSITORY/git/refs/tags/$TAG \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token ${{ github.token }}") | ||
if [[ $RESP_CODE != "204" ]]; | ||
echo "Unable to delete existing TAG $TAG - HTTP response code was $RESP_CODE" | ||
exit 1 | ||
fi | ||
echo "Deleted existing tag $TAG" | ||
fi | ||
- name: Create tag | ||
# Creating a release will also create a tag, so only create explicitly create tag if not creating release | ||
if: ${{ inputs.release == 'false' }} | ||
shell: bash | ||
env: | ||
TAG: ${{ inputs.tag }} | ||
GITHUB_REPOSITORY: ${{ github.repository }} | ||
run: | | ||
# Create new tag via GitHub API | ||
# https://docs.github.com/en/rest/reference/git#create-a-reference | ||
RESP_CODE=$(curl -w %{http_code} -s -o /dev/null \ | ||
-X POST https://api.github.com/repos/$GITHUB_REPOSITORY/git/refs \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token ${{ github.token }}" \ | ||
-d @- << EOF | ||
{ | ||
"sha": "${{ github.sha }}", | ||
"ref": "refs/tags/$TAG" | ||
} | ||
EOF | ||
) | ||
if [[ $RESP_CODE != "201" ]]; | ||
echo "Unable to create tag $TAG for sha ${{ github.sha }} - HTTP response code was $RESP_CODE" | ||
exit 1 | ||
fi | ||
echo "New tag $TAG created for sha ${{ github.sha }}" | ||
- name: Create release | ||
if: ${{ inputs.release == 'true' }} | ||
shell: bash | ||
env: | ||
TAG: ${{ inputs.tag }} | ||
RELEASE_DESCRIPTION: ${{ inputs.release_description }} | ||
GITHUB_REPOSITORY: ${{ github.repository }} | ||
run: | | ||
# Create new release via GitHub API | ||
# https://docs.github.com/en/rest/releases/releases#create-a-release | ||
# Escape double quotes '"' => '\"' | ||
RELEASE_DESCRIPTION=${RELEASE_DESCRIPTION//\"/\\\"} | ||
RESP_CODE=$(curl -w %{http_code} -s -o /dev/null \ | ||
-X POST https://api.github.com/repos/$GITHUB_REPOSITORY/releases \ | ||
-H "Accept: application/vnd.github.v3+json" \ | ||
-H "Authorization: token ${{ github.token }}" \ | ||
-d @- << EOF | ||
{ | ||
"tag_name": "$TAG", | ||
"target_commitish": "${{ github.sha }}", | ||
"name": "$TAG", | ||
"body": "$RELEASE_DESCRIPTION", | ||
"draft": false, | ||
"prerelease": false | ||
} | ||
EOF | ||
) | ||
if [[ $RESP_CODE != "201" ]]; | ||
echo "Unable to create release for tag $TAG - HTTP response code was $RESP_CODE" | ||
exit 1 | ||
fi | ||
echo "New release $TAG created" |