-
Notifications
You must be signed in to change notification settings - Fork 5
149 lines (138 loc) · 5.47 KB
/
restack.yml
File metadata and controls
149 lines (138 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Reusable workflow: restack after sync PR merge.
# Triggered by a consuming repo on pull_request closed+merged for repo-sync/
# branches, or via workflow_dispatch for stuck stack recovery.
#
# Implements: watermark update, rebase --onto for squash merge compatibility,
# auto-merge enable on new stack bottom, CI failure -> human assignment,
# conflict -> agent invocation with mandatory human sign-off.
name: restack
on:
workflow_call:
inputs:
public_repo:
description: "Public repo (e.g. warpdotdev/warp-public)."
required: true
type: string
private_repo:
description: "Private repo (e.g. warpdotdev/warp-internal)."
required: true
type: string
escalate_to:
description: "GitHub team or user to escalate to on timeout."
required: false
type: string
default: "@oncall-client-primary"
app_id:
description: "GitHub App ID."
required: true
type: string
repo_sync_ref:
description: "Ref of the repo-sync repo to use."
required: false
type: string
default: "main"
secrets:
app_private_key:
description: "GitHub App private key."
required: true
warp_api_key:
description: "Warp API key for the conflict-resolution agent."
required: false
# workflow_dispatch is used for stuck-stack recovery.
workflow_dispatch:
inputs:
pr_number:
description: "Stuck PR number to restack."
required: true
type: string
public_repo:
description: "Public repo (e.g. warpdotdev/warp-public)."
required: true
type: string
private_repo:
description: "Private repo (e.g. warpdotdev/warp-internal)."
required: true
type: string
escalate_to:
description: "GitHub team or user to escalate to on timeout."
required: false
type: string
default: "@oncall-client-primary"
# Serialize ALL restack operations to prevent concurrent rebases.
concurrency:
group: repo-sync-restack-${{ github.repository }}
cancel-in-progress: false
jobs:
restack:
runs-on: ubuntu-latest
# Run if: (a) the PR was merged (normal restack), (b) dispatched for
# stuck stack recovery, or (c) labeled with repo-sync:needs-restack
# (triggered by the approve workflow for auto-retargeted PRs).
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'repo-sync/')) ||
(github.event.action == 'labeled' &&
github.event.label.name == 'repo-sync:needs-restack' &&
startsWith(github.event.pull_request.head.ref, 'repo-sync/'))
permissions:
contents: write
pull-requests: write
env:
PUBLIC_REPO: ${{ inputs.public_repo }}
PRIVATE_REPO: ${{ inputs.private_repo }}
ESCALATE_TO: ${{ inputs.escalate_to }}
steps:
# Generate a token for both workflow_call and workflow_dispatch.
# For workflow_call, secrets are passed from the caller.
# For workflow_dispatch, secrets come from the repo's own secrets.
- name: Generate installation token
id: token
uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
with:
app-id: ${{ inputs.app_id }}
private-key: ${{ secrets.app_private_key || secrets.REPO_SYNC_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: Set GH_TOKEN
run: echo "GH_TOKEN=${{ steps.token.outputs.token }}" >> "$GITHUB_ENV"
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
token: ${{ steps.token.outputs.token }}
- name: Checkout repo-sync tooling
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
repository: warpdotdev/repo-sync
ref: ${{ inputs.repo_sync_ref }}
path: .repo-sync
token: ${{ steps.token.outputs.token }}
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
- name: Install repo-sync tools
run: pip install -e .repo-sync
- name: Build conflict resolution agent image
run: docker build -f .repo-sync/docker/conflict-resolution/Dockerfile -t repo-sync-conflict-resolution .repo-sync
- name: Configure git identity
run: |
git config --global user.name "warp-repo-sync[bot]"
git config --global user.email "270220925+warp-repo-sync[bot]@users.noreply.github.com"
# All restack logic (context derivation, direction detection, watermark
# update, find next PR, rebase, push, label management) is in Python.
# The event payload provides all needed GitHub context.
- name: Run restack
run: |
python -m repo_sync.workflows.cli restack-pr \
--event-path "$GITHUB_EVENT_PATH" \
--event-name "${{ github.event_name }}" \
--event-action "${{ github.event.action || '' }}" \
--gh-repo "${{ github.repository }}" \
--public-repo "${PUBLIC_REPO}" \
--private-repo "${PRIVATE_REPO}" \
--default-branch "${{ github.event.repository.default_branch }}" \
--escalate-to "${ESCALATE_TO}" \
--repo-dir .
env:
WARP_API_KEY: ${{ secrets.warp_api_key }}