Skip to content

Commit 95ebaa6

Browse files
committed
Initial checkout-merge action
0 parents  commit 95ebaa6

File tree

5 files changed

+187
-0
lines changed

5 files changed

+187
-0
lines changed

.github/workflows/checkout.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Word Counts
2+
on:
3+
pull_request_target:
4+
5+
jobs:
6+
count:
7+
name: Word Count
8+
permissions:
9+
contents: read
10+
pull-requests: read
11+
runs-on: ubuntu-latest
12+
if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
13+
steps:
14+
- name: checkout
15+
uses: actions/checkout@v2
16+
- name: checkout-merge
17+
if: "contains(github.event_name, 'pull_request')"
18+
uses: ./
19+
- name: check-count
20+
if: env.MERGE_FAILED != '1'
21+
id: count
22+
run: git ls-files -z | xargs -0 wc

LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Josh Soref
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Checkout Merge
2+
3+
This action synthesizes the merge commit GitHub would give you via `refs/pull/X/merge`.
4+
5+
With GitHub.com's current implementation as of Dec 8, 2021, if it was able to make a
6+
merge commit, and then a push causes the current state to be not mergable, the
7+
`refs/pull/X/merge` ref may stick around resulting in confusing output.
8+
9+
With this action, instead, you will not get a merge commit.
10+
11+
If you use [@actions/checkout](https://github.com/actions/checkout) to try to
12+
check out `refs/pull/X/merge` and it doesn't exist, the action will make three
13+
attempts (failing each time), and then leave your workflow in a failed state
14+
and your user with a fairly confusing log.
15+
16+
If you instead use [@actions/checkout](https://github.com/actions/checkout) to
17+
check out the base commit, then you can use this action to get a merge commit.
18+
If it isn't able to, it can produce an error message that is hopefully easier
19+
for users to understand, and allow you to decide whether your workflow should
20+
✅ or ❌.
21+
22+
## Usage
23+
24+
```yaml
25+
- name: checkout
26+
uses: actions/checkout@v2
27+
- name: checkout-merge
28+
if: "contains(github.event_name, 'pull_request')"
29+
uses: check-spelling/checkout-merge@main
30+
with:
31+
# Base for merge (it will be checked out)
32+
# Default: ${{ github.event.pull_request.base.sha }}
33+
base_ref: ''
34+
35+
# Head for merge (it will be fetched and merged)
36+
# Default: ${{ github.event.pull_request.head.sha }}
37+
head_ref: ''
38+
39+
# Relative path under $GITHUB_WORKSPACE to the repository
40+
# Default: .
41+
path: ''
42+
43+
# Suppress reporting errors (consumers would report the message themselves)
44+
# By default, this action reports errors in the workflow overview.
45+
# If you want to handle reporting the error in some other manner,
46+
# you can set this flag.
47+
# Default: false
48+
do_not_report: ''
49+
- if: env.MERGE_FAILED != '1'
50+
run: ...
51+
```
52+
53+
### Outputs
54+
55+
* `message` - Message describing what prevented the action from producing a merge commit.
56+
57+
* `status` - `success` or `failed`
58+
59+
### Environment products
60+
61+
* `$MERGE_FAILED` will be set to `1` if a merge can't be created.

action.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: 'Checkout Merge'
2+
description: 'Generate a merge commit'
3+
author: 'jsoref'
4+
branding:
5+
icon: 'git-commit'
6+
color: 'green'
7+
inputs:
8+
base_ref:
9+
description: |
10+
This commit will be refetched (to give the merge the best chance of
11+
succceeding) and used as the base for the merge.
12+
default: ${{ github.event.pull_request.base.sha }}
13+
required: false
14+
head_ref:
15+
description: |
16+
This commit will be fetched and merged into the base commit.
17+
default: ${{ github.event.pull_request.head.sha }}
18+
required: false
19+
path:
20+
description: 'Relative path under $GITHUB_WORKSPACE to the repository'
21+
default: "."
22+
required: false
23+
do_not_report:
24+
description: 'Suppress reporting errors (consumers would report the message themselves)'
25+
default: ''
26+
required: false
27+
outputs:
28+
message:
29+
description: "User facing message about attempt to merge"
30+
value: ${{ steps.merge.outputs.message }}
31+
status:
32+
description: "Whether the merge succeeded"
33+
value: ${{ steps.merge.status }}
34+
runs:
35+
using: composite
36+
steps:
37+
- id: merge
38+
shell: bash
39+
env:
40+
INPUT_BASE_REF: ${{ inputs.base_ref }}
41+
INPUT_HEAD_REF: ${{ inputs.head_ref }}
42+
INPUT_PATH: ${{ inputs.path }}
43+
INPUT_DO_NOT_REPORT: ${{ inputs.do_not_report }}
44+
run: ${{ github.action_path }}/merge

merge

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
report_failure() {
3+
echo "MERGE_FAILED=1" >> "$GITHUB_ENV"
4+
echo '::set-output name=status::failed'
5+
echo "::set-output name=message::$1"
6+
if [ -z "$INPUT_DO_NOT_REPORT" ]; then
7+
echo "::error ::$1"
8+
fi
9+
exit 0
10+
}
11+
12+
cd "$INPUT_PATH" || report_failure "Could not change to input_path ($INPUT_PATH)"
13+
SENDER=$(jq -r .sender.login "$GITHUB_EVENT_PATH")
14+
USER_JSON=$(mktemp)
15+
curl -s "$GITHUB_API_URL/users/$SENDER" -o "$USER_JSON"
16+
export GIT_AUTHOR_NAME=$(jq -r .name "$USER_JSON")
17+
export GIT_AUTHOR_EMAIL=$(jq -r '.email // empty' "$USER_JSON")
18+
if [ -z "$GIT_AUTHOR_EMAIL" ]; then
19+
GIT_AUTHOR_EMAIL=$(jq -r '( (.id|tostring) + "+" + .login + "@users.noreply.github.com")' "$GITHUB_EVENT_PATH")
20+
fi
21+
export GIT_COMMITTER_NAME=GitHub
22+
export GIT_COMMITTER_EMAIL=noreply@github.com
23+
git fetch --unshallow origin "$INPUT_BASE_REF" ||
24+
report_failure "Can't get history for base_ref ($INPUT_BASE_REF). Please contact support"
25+
GITHUB_BASE_SHA=$(git rev-parse FETCH_HEAD)
26+
27+
git -c advice.detachedHead=false checkout "$GITHUB_BASE_SHA" || {
28+
git status
29+
report_failure "Couldn't check out base_ref ($INPUT_BASE_REF); repository is probably dirty."
30+
}
31+
32+
git fetch origin "$INPUT_HEAD_REF" ||
33+
report_failure "Can't get head_ref ($INPUT_HEAD_REF). Please contact support"
34+
35+
GITHUB_HEAD_SHA=$(git rev-parse FETCH_HEAD)
36+
git merge -m "Merge $GITHUB_HEAD_SHA into $GITHUB_BASE_SHA" FETCH_HEAD ||
37+
report_failure "Can't generate merge; there's probably a conflict. Resolve it to get workflow feedback."
38+
39+
echo '::set-output name=status::success'

0 commit comments

Comments
 (0)