diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml index 982c17a..33446ca 100644 --- a/.github/workflows/auto-tag.yml +++ b/.github/workflows/auto-tag.yml @@ -1,3 +1,4 @@ +name: Auto-tag on: push: tags: @@ -9,6 +10,3 @@ jobs: steps: - name: Auto-tag uses: silverstripe/gha-auto-tag@main - with: - ref: ${{ github.ref }} - sha: ${{ github.sha }} diff --git a/README.md b/README.md index d26c6a9..7b86fc2 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,17 @@ Create a tag and an optional release -Note: this ctions seems to have issues creating tags and releases on forked repos, though it's fine on non-forked repos +### 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 diff --git a/action.yml b/action.yml index 58f0ef2..4d36439 100644 --- a/action.yml +++ b/action.yml @@ -1,9 +1,9 @@ name: Tag and release + description: GitHub Action to create a tag and an optional release + inputs: - sha: - type: string - required: true + # Note: there is an explicit reason why there is no sha input parameter - see the readme tag: type: string required: true @@ -19,9 +19,7 @@ inputs: type: string required: false default: '' - github_token: - description: "GitHub secret token" - required: true + runs: using: composite steps: @@ -29,15 +27,9 @@ runs: - name: Validate inputs shell: bash env: - SHA: ${{ inputs.sha }} TAG: ${{ inputs.tag }} - BODY: ${{ inputs.body }} run: | - if ! [[ "$SHA" =~ ^[0-9a-f]{40}$ ]]; then - echo "Invalid sha" - exit 1 - fi - if [[ "$TAG" =~ [^a-z0-9\.\-] ]]; then + if [[ "$TAG" =~ [^0-9A-Za-z\.\-] ]]; then echo "Invalid tag" exit 1 fi @@ -46,6 +38,8 @@ runs: if: ${{ inputs.release == 'true' && inputs.delete_existing == 'true' }} shell: bash env: + # Add string inputs to memory instead of using string substitution in shell script + # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable TAG: ${{ inputs.tag }} run: | echo "Deleting old release for $TAG if it exists" @@ -61,85 +55,63 @@ runs: -H "Authorization: token ${{ github.token }}" echo "Deleted existing release $RELEASE_ID for tag $TAG" else - echo "Could not find an existing release for tag $TAG" + echo "Did not find an existing release for tag $TAG" fi - # This fails "Resource not accessible by integration" - even with token passed in - # Note the use of ${{ inputs.github_token }} instead of ${{ github.token }} - name: Delete existing tag if one exists if: ${{ inputs.delete_existing == 'true' }} shell: bash - # Add string inputs to memory instead of using string substitution in shell script - # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable env: TAG: ${{ inputs.tag }} run: | echo "Deleting old $TAG tag if it exists" - # Delete tag via GitHub API - # https://docs.github.com/en/rest/reference/git#delete-a-reference 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 ${{ inputs.github_token }}" - - # - name: Checkout code - # if: ${{ inputs.release == 'false' }} - # uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e # @v2 - # with: - # fetch-depth: 50 - - # This fails - # ! [remote rejected] mytag -> mytag (refusing to allow a GitHub App to create or update workflow `.github/workflows/test.yml` without `workflows` permission) - # - name: Create tag - # if: ${{ inputs.release == 'false' }} - # shell: bash - # env: - # SHA: ${{ inputs.sha }} - # TAG: ${{ inputs.tag }} - # run: | - # # debug - # git log - # # Use raw git commands, otherwise we get "Resource not accessible by integration" - # # and the tag is not created, even if parent job is run with permission: write-all - # # This is despite the fact we can create a release via the API which generates a tag - # git checkout "$SHA" - # git tag "$TAG" - # git push origin "$TAG" - # echo "New tag $TAG created for sha $SHA" + -X GET https://api.github.com/repos/${{ github.repository }}/git/refs/tags \ + -H "Accept: application/vnd.github.v3+json" > __.json + FOUND=0 + # Check there are any tags so we can use jq array selector later + if [[ $(jq 'map(type)' __.json) =~ object ]]; then + if [ $(jq '.[].ref == "refs/tags/${{ inputs.tag }}"' __.json) == "true" ]; then + FOUND=1 + fi + fi + if [ $FOUND == 1 ]; then + # Delete tag via GitHub API + # https://docs.github.com/en/rest/reference/git#delete-a-reference + 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 }}" + echo "Deleted existing tag $TAG" + else + echo "Did not find an existing tag for $TAG" + fi - # Note the use of ${{ inputs.github_token }} instead of ${{ github.token }} - 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: - SHA: ${{ inputs.sha }} TAG: ${{ inputs.tag }} run: | - # TODO: remove - # SHA=${{ github.sha }} - echo "SHA is $SHA" - echo "TAG is $TAG" - echo "url is https://api.github.com/repos/${{ github.repository }}/git/refs" # Create new tag via GitHub API # https://docs.github.com/en/rest/reference/git#create-a-reference curl -s \ -X POST https://api.github.com/repos/${{ github.repository }}/git/refs \ -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token ${{ inputs.github_token }}" \ + -H "Authorization: token ${{ github.token }}" \ -d @- << EOF { - "sha": "$SHA", + "sha": "${{ github.sha }}", "ref": "refs/tags/$TAG" } EOF - echo "New tag $TAG created for sha $SHA" + echo "New tag $TAG created for sha ${{ github.sha }}" - # Creating a release will also create a tag - name: Create release if: ${{ inputs.release == 'true' }} shell: bash env: - SHA: ${{ inputs.sha }} TAG: ${{ inputs.tag }} BODY: ${{ inputs.body }} run: | @@ -154,7 +126,7 @@ runs: -d @- << EOF { "tag_name": "$TAG", - "target_commitish": "$SHA", + "target_commitish": "${{ github.sha }}", "name": "$TAG", "body": "$BODY", "draft": false, @@ -162,4 +134,3 @@ runs: } EOF echo "New release $TAG created" -# ^ todo: test inputs.body with a single double quote in it \ No newline at end of file