Skip to content

Commit 8d3d858

Browse files
authored
Merge pull request #63 from input-output-hk/3rd-party-gha
Adds ci compatible with fork prs
2 parents a757cd4 + 78f656d commit 8d3d858

File tree

3 files changed

+191
-1
lines changed

3 files changed

+191
-1
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Checkout and merge PR
2+
3+
description: >
4+
Checkout base and PR branch, create local merge commit with smart shallow
5+
fetch. Works in manual dispatch, PR, push and schedule contexts. Compatible
6+
with fork PRs.
7+
8+
inputs:
9+
base_ref:
10+
description: 'Base branch ref (typically github.event.pull_request.base.ref)'
11+
required: true
12+
13+
head_ref:
14+
description: 'The head branch ref of the PR (typically github.head_ref || github.ref_name)'
15+
required: true
16+
17+
pr_number:
18+
description: 'PR number (typically github.event.pull_request.number)'
19+
required: false
20+
21+
runs:
22+
using: composite
23+
steps:
24+
- if: inputs.pr_number != ''
25+
env:
26+
GH_TOKEN: ${{ github.token }}
27+
run: |
28+
git config --local user.name "GitHub Actions"
29+
git config --local user.email "[email protected]"
30+
git fetch --no-tags --depth=10 origin ${{ inputs.base_ref }}
31+
git fetch --no-tags --depth=10 origin pull/${{ inputs.pr_number }}/head:pr
32+
33+
# Check if this is a fork PR
34+
if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then
35+
36+
echo "Detected forked PR -- adding fork remote."
37+
PR_REMOTE=$(gh pr view ${{ inputs.pr_number }} --json headRepositoryOwner,headRepository \
38+
--jq '"\(.headRepositoryOwner.login)/\(.headRepository.name)"')
39+
40+
if [ -n "$PR_REMOTE" ]; then
41+
git remote add fork "https://github.com/$PR_REMOTE"
42+
git fetch fork "${{ inputs.head_ref }}"
43+
UPSTREAM="fork"
44+
else
45+
UPSTREAM="origin"
46+
fi
47+
else
48+
echo "Detected same-repo PR."
49+
UPSTREAM="origin"
50+
fi
51+
52+
git fetch --no-tags --depth=10 "$UPSTREAM" "refs/heads/${{ inputs.head_ref }}:refs/remotes/$UPSTREAM/${{ inputs.head_ref }}"
53+
54+
git checkout -b ${{ inputs.head_ref }} FETCH_HEAD
55+
if git merge --no-ff --no-edit pr; then
56+
echo "Merge succeeded."
57+
else
58+
echo "Merge failed, possibly due to shallow history. Retrying with deeper fetch..."
59+
git fetch --unshallow || git fetch --depth=50
60+
61+
if git merge --no-ff --no-edit pr; then
62+
echo "Merge succeeded after deeper fetch."
63+
else
64+
echo "Merge conflict detected."
65+
exit 1
66+
fi
67+
fi
68+
69+
echo "Merged commit HEAD is:"
70+
git rev-parse HEAD
71+
git log -1 --oneline
72+
73+
echo "Setting upstream branch to: $UPSTREAM/${{ inputs.head_ref }}"
74+
git branch --set-upstream-to="$UPSTREAM/${{ inputs.head_ref }}" HEAD
75+
76+
echo "Confirmation of upstream:"
77+
git status -sb
78+
shell: bash
79+
80+
- if: inputs.pr_number == ''
81+
run: echo "Not a PR event -- no merge required"
82+
shell: bash
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Detect PR context
2+
3+
description: >
4+
Detects pull request context, outputs PR number, refs, and trust level.
5+
Compatible with fork PRs.
6+
7+
outputs:
8+
base_ref:
9+
description: Base branch ref
10+
value: ${{ steps.internal-detect-pr.outputs.base_ref }}
11+
12+
event_name:
13+
description: GitHub event name
14+
value: ${{ steps.internal-detect-pr.outputs.event_name }}
15+
16+
head_ref:
17+
description: Head branch ref
18+
value: ${{ steps.internal-detect-pr.outputs.head_ref }}
19+
20+
is_trusted:
21+
description: Trusted status
22+
value: ${{ steps.internal-detect-pr.outputs.is_trusted }}
23+
24+
pr_number:
25+
description: Pull request number, if applicable
26+
value: ${{ steps.internal-detect-pr.outputs.pr_number }}
27+
28+
runs:
29+
using: composite
30+
steps:
31+
- name: Detect context
32+
env:
33+
GH_TOKEN: ${{ github.token }}
34+
id: internal-detect-pr
35+
run: |
36+
HEAD_REPO="${{ github.event.pull_request.head.repo.full_name }}"
37+
REPO="${{ github.repository }}"
38+
39+
if [ "${{ github.event_name }}" = "pull_request" ]; then
40+
echo "PR context detected."
41+
echo "pr_number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
42+
echo "head_ref=${{ github.event.pull_request.head.ref }}" >> "$GITHUB_OUTPUT"
43+
echo "base_ref=${{ github.event.pull_request.base.ref }}" >> "$GITHUB_OUTPUT"
44+
45+
if [ "$HEAD_REPO" = "$REPO" ]; then
46+
echo "is_trusted=true" >> "$GITHUB_OUTPUT"
47+
else
48+
echo "is_trusted=false" >> "$GITHUB_OUTPUT"
49+
fi
50+
51+
elif [ -n "${{ github.event.inputs.pr_number }}" ]; then
52+
echo "Manual dispatch detected."
53+
54+
PR_DATA=$(gh pr view ${{ github.event.inputs.pr_number }} --repo "$REPO" \
55+
--json headRefName,baseRefName -q '{ "head_ref": .headRefName, "base_ref": .baseRefName }')
56+
57+
HEAD_REF=$(jq -r .head_ref <<< "$PR_DATA")
58+
BASE_REF=$(jq -r .base_ref <<< "$PR_DATA")
59+
60+
echo "pr_number=${{ github.event.inputs.pr_number }}" >> "$GITHUB_OUTPUT"
61+
echo "head_ref=$HEAD_REF" >> "$GITHUB_OUTPUT"
62+
echo "base_ref=$BASE_REF" >> "$GITHUB_OUTPUT"
63+
echo "is_trusted=true" >> "$GITHUB_OUTPUT"
64+
65+
else
66+
echo "No PR context detected. Using default branch."
67+
echo "head_ref=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
68+
echo "base_ref=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
69+
echo "is_trusted=true" >> "$GITHUB_OUTPUT"
70+
fi
71+
shell: bash
72+
73+
- name: Print detected context
74+
run: |
75+
echo "Event: ${{ github.event_name }}"
76+
echo "PR number: ${{ steps.internal-detect-pr.outputs.pr_number }}"
77+
echo "Head ref: ${{ steps.internal-detect-pr.outputs.head_ref }}"
78+
echo "Base ref: ${{ steps.internal-detect-pr.outputs.base_ref }}"
79+
echo "Trusted run: ${{ steps.internal-detect-pr.outputs.is_trusted }}"
80+
shell: bash

.github/workflows/nix-jobs-test.yaml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,42 @@
11
on:
2+
workflow_dispatch:
3+
inputs:
4+
pr_number:
5+
description: Optional PR number, for maintainer use
6+
required: false
7+
8+
push:
9+
branches:
10+
- main
11+
212
pull_request:
313

14+
permissions:
15+
contents: read
16+
pull-requests: read
17+
418
jobs:
519
nix-jobs-test:
620
name: "Test nix jobs"
721
runs-on: ubuntu-latest
822
steps:
923
- name: Checkout
1024
uses: actions/checkout@v4
25+
26+
# This step allows for maintainer workflow dispatch of forked PRs with a
27+
# declared PR input number.
28+
- name: Detect PR context
29+
id: detect-pr
30+
uses: ./.github/actions/detect-pr
31+
32+
# For PRs, checkout a merge base, including for forked PRs.
33+
- name: Checkout and merge PR
34+
uses: ./.github/actions/checkout-merge
1135
with:
12-
ref: "${{github.head_ref || github.ref_name}}"
36+
base_ref: ${{ steps.detect-pr.outputs.base_ref }}
37+
head_ref: ${{ steps.detect-pr.outputs.head_ref }}
38+
pr_number: ${{ steps.detect-pr.outputs.pr_number }}
39+
1340
- name: Install Nix
1441
uses: cachix/install-nix-action@v27
1542
with:
@@ -18,6 +45,7 @@ jobs:
1845
experimental-features = fetch-closure flakes nix-command
1946
substituters = https://cache.iog.io https://cache.nixos.org/
2047
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
48+
2149
- name: Test
2250
run: |
2351
nix --version

0 commit comments

Comments
 (0)