Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,80 @@ jobs:
git push --force --delete origin "${TO_DELETE}"
env:
TO_DELETE: ${{ steps.setup-test-branch.outputs.branch-name }}

test-allow-empty: # verify allow-empty: true creates a commit even when there are no file changes
runs-on: ubuntu-latest
needs: [check-not-fork]
permissions:
contents: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: true
- name: Setup test branch
id: setup-test-branch
run: |
BRANCH_NAME="test_allow-empty-$(date +%s)"

git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'

git checkout -b $BRANCH_NAME
git push --set-upstream origin $BRANCH_NAME

# output status here to manually verify there are no file changes
git status --porcelain=v2 --branch --untracked-files=no

PARENT_SHA=$(git rev-parse HEAD)
echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "parent-sha=$PARENT_SHA" >> $GITHUB_OUTPUT
- uses: ./
id: test-action
with:
token: ${{ github.token }}
allow-empty: true
commit-message: ${{ steps.setup-test-branch.outputs.branch-name }}
- name: Validate empty commit was created
run: |
if [[ -z "${RESPONSE}" ]]; then
echo "Error: commit-response is empty; expected a commit to be created."
exit 1
fi

changedFilesIfAvailable=$(echo "${RESPONSE}" | jq -r '.data.createCommitOnBranch.commit.changedFilesIfAvailable')
if [[ "$changedFilesIfAvailable" -ne 0 ]]; then
echo "Error: changedFilesIfAvailable expected 0 but got $changedFilesIfAvailable."
exit 1
fi

# Fetch the branch from the remote and confirm the commit is truly empty
# (its tree SHA equals its parent's tree SHA) and that HEAD advanced.
git fetch origin "${BRANCH}"
NEW_HEAD=$(git rev-parse "origin/${BRANCH}")
if [[ "$NEW_HEAD" == "${PARENT_SHA}" ]]; then
echo "Error: branch HEAD did not advance; no commit was created."
exit 1
fi

NEW_TREE=$(git rev-parse "origin/${BRANCH}^{tree}")
PARENT_TREE=$(git rev-parse "origin/${BRANCH}~^{tree}")
if [[ "$NEW_TREE" != "$PARENT_TREE" ]]; then
echo "Error: new commit tree ($NEW_TREE) differs from parent tree ($PARENT_TREE); commit is not empty."
exit 1
fi

echo "Validation passed: empty commit created on top of ${PARENT_SHA}."
env:
RESPONSE: ${{ steps.test-action.outputs.commit-response }}
BRANCH: ${{ steps.setup-test-branch.outputs.branch-name }}
PARENT_SHA: ${{ steps.setup-test-branch.outputs.parent-sha }}
- name: Delete test branch
if: ${{ always() }}
run: |
git push --force --delete origin "${TO_DELETE}"
env:
TO_DELETE: ${{ steps.setup-test-branch.outputs.branch-name }}

test-persist-credentials-false-branch-on-remote:
runs-on: ubuntu-latest
needs: [check-not-fork]
Expand Down
23 changes: 16 additions & 7 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ inputs:
default: 'false'
success-if-no-changes:
required: true
description: 'Whether to return success if no changes are detected: true/false'
description: 'Whether to return success if no changes are detected. Has no effect when allow-empty is true: true/false'
default: 'false'
allow-empty:
required: true
description: 'Whether to create an empty commit when there are no changes (supersedes success-if-no-changes): true/false'
default: 'false'
token:
required: true
Expand Down Expand Up @@ -129,13 +133,17 @@ runs:
done

if [[ "$additions" == "" && "$deletions" == "" ]]; then
echo "No changes to commit"
echo "any_changed=false" >> $GITHUB_OUTPUT

if [[ "${SUCCESS_IF_NO_CHANGES}" == "true" ]]; then
exit 0
if [[ "${ALLOW_EMPTY}" == "true" ]]; then
echo "No changes detected; creating an empty commit (allow-empty=true)"
else
exit 1
echo "No changes to commit"
echo "any_changed=false" >> $GITHUB_OUTPUT

if [[ "${SUCCESS_IF_NO_CHANGES}" == "true" ]]; then
exit 0
else
exit 1
fi
fi
fi

Expand All @@ -153,6 +161,7 @@ runs:
echo "deletions=$deletions" >> $GITHUB_OUTPUT
env:
SUCCESS_IF_NO_CHANGES: ${{ inputs.success-if-no-changes }}
ALLOW_EMPTY: ${{ inputs.allow-empty }}

- name: Commit changes
if: ${{ steps.additions-and-deletions.outputs.any_changed == 'true' }}
Expand Down
11 changes: 7 additions & 4 deletions docs/README.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,28 @@ instance, if you create a branch via `git checkout -b my-test-branch` in one of
commit-message: "<commit-message>" # Commit message defaults to "Commit performed by grafana/github-api-commit-action"
create-branch-on-remote: true | false # Whether to create the branch on the remote if it doesn't exist: Defaults to false
stage-all-files: true | false # Whether to additionally stage any changed files in the checkout. Defaults to false
allow-empty: true | false # Whether to create an empty commit when there are no changes (supersedes success-if-no-changes). Defaults to false
success-if-no-changes: true | false # Whether to return success if no changes are detected. Has no effect when allow-empty is true. Defaults to false
token: ${{ github.token }} # Token you want to authenticate with
```

### Example: Using a GitHub App Installation Token

```yaml
- uses: tibdex/github-app-token@v1
- uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
id: get_installation_token
with:
app_id: ${{ secrets.GITHUB_APP_ID }}
installation_id: ${{ secrets.GITHUB_APP_INSTALLATION_ID }}
private_key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
private-key: ${{ vars.GITHUB_APP_PRIVATE_KEY }}

- name: Commit changes
uses: grafana/github-api-commit-action@$TAG_HASH # $TAG
with:
commit-message: "<commit-message>" # Commit message defaults to "Commit performed by grafana/github-api-commit-action"
create-branch-on-remote: true | false # Whether to create the branch on the remote if it doesn't exist already: Defaults to false
stage-all-files: true | false # Whether to additionally stage any changed files in the checkout. Defaults to false
allow-empty: true | false # Whether to create an empty commit when there are no changes (supersedes success-if-no-changes). Defaults to false
success-if-no-changes: true | false # Whether to return success if no changes are detected. Has no effect when allow-empty is true. Defaults to false
token: ${{ steps.get_installation_token.outputs.token }} # Token you want to authenticate with
```

Expand Down