1+ ---
2+ # SPDX-License-Identifier: Apache-2.0
3+ # SPDX-FileCopyrightText: 2025 The Linux Foundation
4+
5+ name : github2gerrit-reusable-workflow-v2
6+
7+ on :
8+ workflow_call :
9+ inputs :
10+ SUBMIT_SINGLE_COMMITS :
11+ description : " Submit one commit at a time to the Gerrit repository"
12+ required : false
13+ default : false
14+ type : boolean
15+ USE_PR_AS_COMMIT :
16+ description : " Use PR body and title as commit message"
17+ required : false
18+ default : false
19+ type : boolean
20+ FETCH_DEPTH :
21+ description : " fetch-depth for the clone. (Default: 10)"
22+ required : false
23+ default : " 10"
24+ type : string
25+ GERRIT_KNOWN_HOSTS :
26+ description : " known hosts"
27+ required : true
28+ type : string
29+ GERRIT_SERVER :
30+ description : " Gerrit hostname ex: git.opendaylight.org"
31+ required : false
32+ default : " "
33+ type : string
34+ GERRIT_SERVER_PORT :
35+ description : " Gerrit port. (Default: 29418)"
36+ required : false
37+ default : " 29418"
38+ type : string
39+ GERRIT_PROJECT :
40+ description : " Gerrit project name. ex: releng/builder"
41+ required : false
42+ default : " "
43+ type : string
44+ GERRIT_SSH_USER_G2G :
45+ description : " Gerrit user-id for SSH"
46+ required : true
47+ type : string
48+ GERRIT_SSH_USER_G2G_EMAIL :
49+ description : " Email of the SSH user"
50+ required : true
51+ type : string
52+ ORGANIZATION :
53+ description : " Organization name, e.g. opendaylight"
54+ required : false
55+ type : string
56+ default : ${{ github.repository_owner }}
57+ REVIEWERS_EMAIL :
58+ description : " Committers email list (comma separated) to notify on code-reviews"
59+ required : false
60+ default : " "
61+ type : string
62+ secrets :
63+ GERRIT_SSH_PRIVKEY_G2G :
64+ description : " SSH Private key"
65+ required : true
66+ outputs :
67+ gerrit_change_url :
68+ description : " URL of the Gerrit change request"
69+ value : ${{ jobs.github2gerrit.outputs.change_url }}
70+ gerrit_change_number :
71+ description : " Gerrit change request number"
72+ value : ${{ jobs.github2gerrit.outputs.change_number }}
73+
74+ concurrency :
75+ group : g2g-v2-${{ github.workflow }}-${{ github.run_id }}
76+ cancel-in-progress : true
77+
78+ jobs :
79+ github2gerrit :
80+ name : " Submit PR to Gerrit"
81+ runs-on : ubuntu-latest
82+ timeout-minutes : 15
83+ permissions :
84+ contents : read
85+ pull-requests : write
86+
87+ outputs :
88+ change_url : ${{ env.GERRIT_CHANGE_REQUEST_URL }}
89+ change_number : ${{ env.GERRIT_CHANGE_REQUEST_NUM }}
90+
91+ steps :
92+ - name : " Validate workflow inputs"
93+ if : ${{ inputs.USE_PR_AS_COMMIT && inputs.SUBMIT_SINGLE_COMMITS }}
94+ run : |
95+ echo "::error::USE_PR_AS_COMMIT and SUBMIT_SINGLE_COMMITS cannot be enabled simultaneously"
96+ exit 1
97+
98+ - name : " Setup Python environment"
99+ uses : actions/setup-python@v5
100+ with :
101+ python-version : " 3.11"
102+
103+ - name : " Install dependencies"
104+ run : |
105+ python -m pip install --upgrade pip
106+ pip install "git-review==2.3.1" jq
107+ echo "::notice::Installed git-review $(git review --version)"
108+ echo "::notice::Installed jq $(jq --version)"
109+
110+ - name : " Checkout repository"
111+ uses : actions/checkout@v4
112+ with :
113+ fetch-depth : ${{ inputs.FETCH_DEPTH }}
114+ ref : ${{ github.event.pull_request.head.sha }}
115+ token : ${{ github.token }}
116+
117+ - name : " Setup SSH key"
118+ uses : shimataro/ssh-key-action@d4fffb50872869abe2d9a9098a6d9c5aa7d16be4
119+ with :
120+ key : ${{ secrets.GERRIT_SSH_PRIVKEY_G2G }}
121+ name : " id_rsa"
122+ known_hosts : ${{ inputs.GERRIT_KNOWN_HOSTS }}
123+ config : |
124+ Host ${{ env.GERRIT_SERVER }}
125+ User ${{ inputs.GERRIT_SSH_USER_G2G }}
126+ Port ${{ env.GERRIT_SERVER_PORT || '29418' }}
127+ PubkeyAcceptedKeyTypes +ssh-rsa
128+ IdentityFile ~/.ssh/id_rsa
129+
130+ - name : " Setup environment variables"
131+ run : ./scripts/setup-environment.sh
132+ env :
133+ GITHUB_EVENT_PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }}
134+ GITHUB_EVENT_ISSUE_NUMBER : ${{ github.event.issue.number }}
135+ GITHUB_BASE_REF : ${{ github.base_ref }}
136+
137+ - name : " Parse git review configuration"
138+ run : ./scripts/parse-gitreview.sh
139+ env :
140+ GERRIT_PROJECT_INPUT : ${{ inputs.GERRIT_PROJECT }}
141+ GERRIT_SERVER_INPUT : ${{ inputs.GERRIT_SERVER }}
142+ GERRIT_SERVER_PORT_INPUT : ${{ inputs.GERRIT_SERVER_PORT }}
143+ GITHUB_REPOSITORY : ${{ github.repository }}
144+
145+ - name : " Setup Issue ID lookup (if enabled)"
146+ if : vars.ISSUEID == 'true'
147+ run : |
148+ # Set key to use for JSON lookup
149+ ACTOR="${{ github.actor }}"
150+ ACTOR_ID="${{ github.actor_id }}"
151+ echo "::notice::Using GitHub actor as lookup key: $ACTOR [$ACTOR_ID]"
152+ echo "key=$ACTOR" >> "$GITHUB_ENV"
153+
154+ - name : " Get ticket from JSON lookup table"
155+ if : vars.ISSUEID == 'true'
156+ uses : lfit/releng-reusable-workflows/.github/actions/json-key-value-lookup-action@main
157+ with :
158+ json : ${{ vars.ISSUE_ID_LOOKUP_JSON }}
159+ key : ${{ env.key }}
160+
161+ - name : " Set Issue ID in environment"
162+ if : vars.ISSUEID == 'true'
163+ run : |
164+ if [[ -n "${{ env.value }}" ]]; then
165+ echo "SET_ISSUE_ID=${{ env.value }}" >> "$GITHUB_ENV"
166+ echo "::notice::Issue ID set: ${{ env.value }}"
167+ fi
168+
169+ - name : " Configure git for Gerrit"
170+ run : ./scripts/setup-git.sh
171+ env :
172+ GERRIT_SSH_USER_G2G : ${{ inputs.GERRIT_SSH_USER_G2G }}
173+ GERRIT_SSH_USER_G2G_EMAIL : ${{ inputs.GERRIT_SSH_USER_G2G_EMAIL }}
174+
175+ - name : " Handle PR updates and Change-ID reuse"
176+ if : >-
177+ github.event_name == 'pull_request_target' &&
178+ (github.event.action == 'reopened' || github.event.action == 'synchronize')
179+ run : ./scripts/handle-pr-updates.sh
180+ env :
181+ ORGANIZATION : ${{ inputs.ORGANIZATION }}
182+ GITHUB_EVENT_ACTION : ${{ github.event.action }}
183+ GH_TOKEN : ${{ github.token }}
184+
185+ - name : " Process PR commits"
186+ run : ./scripts/process-commits.sh
187+ env :
188+ SUBMIT_SINGLE_COMMITS : ${{ inputs.SUBMIT_SINGLE_COMMITS }}
189+ USE_PR_AS_COMMIT : ${{ inputs.USE_PR_AS_COMMIT }}
190+ GITHUB_EVENT_PULL_REQUEST_BASE_SHA : ${{ github.event.pull_request.base.sha }}
191+ GITHUB_SHA : ${{ github.sha }}
192+ GITHUB_EVENT_ACTION : ${{ github.event.action }}
193+ SET_ISSUE_ID : ${{ env.SET_ISSUE_ID }}
194+ ISSUEID_ENABLED : ${{ vars.ISSUEID }}
195+ GH_TOKEN : ${{ github.token }}
196+
197+ - name : " Handle PR title and body as commit message"
198+ if : ${{ inputs.USE_PR_AS_COMMIT && github.event_name == 'pull_request_target' }}
199+ run : |
200+ echo "::notice::Using PR title and body as commit message"
201+
202+ # Get PR title and body
203+ gh pr view "$PR_NUMBER" --json title,body > pr_data.json
204+
205+ # Extract title and body
206+ jq -r '.title // ""' pr_data.json > pr_title.txt
207+ echo "" >> pr_title.txt # Blank line between title and body
208+ jq -r '.body // ""' pr_data.json > pr_body.txt
209+
210+ # Combine title and body
211+ cat pr_title.txt pr_body.txt > pr_commit.txt
212+
213+ # Get author info and signed-off-by lines
214+ if [[ -s author-info.txt && -s signed-off-by-final.txt ]]; then
215+ author=$(cat author-info.txt)
216+ echo "" >> pr_commit.txt # Blank line before trailers
217+ cat signed-off-by-final.txt >> pr_commit.txt
218+
219+ # Amend commit with PR content
220+ git commit --amend --author "$author" -F pr_commit.txt
221+ echo "::notice::Updated commit with PR title and body"
222+ fi
223+ env :
224+ GH_TOKEN : ${{ github.token }}
225+
226+ - name : " Submit to Gerrit"
227+ run : ./scripts/submit-to-gerrit.sh
228+ env :
229+ REVIEWERS_EMAIL : ${{ inputs.REVIEWERS_EMAIL }}
230+ GERRIT_SSH_USER_G2G : ${{ inputs.GERRIT_SSH_USER_G2G }}
231+ GERRIT_SERVER : ${{ env.GERRIT_SERVER }}
232+ GITHUB_SERVER_URL : ${{ github.server_url }}
233+ GITHUB_REPOSITORY : ${{ github.repository }}
234+ GITHUB_RUN_ID : ${{ github.run_id }}
235+
236+ - name : " Add GitHub reference to PR"
237+ if : env.GERRIT_CR_URL_CID != ''
238+ uses : actions/github-script@v7
239+ with :
240+ script : |
241+ const changeUrls = `${{ env.GERRIT_CR_URL_CID }}`;
242+ const prNumber = `${{ env.PR_NUMBER }}`;
243+ const organization = `${{ inputs.ORGANIZATION }}`;
244+ const gerritServer = `${{ env.GERRIT_SERVER }}`;
245+
246+ const message = `The pull-request PR-${prNumber} has been submitted to Gerrit [${organization}](https://${gerritServer})!
247+
248+ **Gerrit Change(s):**
249+ ${changeUrls}
250+
251+ **Important:** This PR will be closed automatically. Re-opening will create a new change - use the Gerrit link above for updates.`;
252+
253+ await github.rest.issues.createComment({
254+ issue_number: context.issue.number,
255+ owner: context.repo.owner,
256+ repo: context.repo.repo,
257+ body: message
258+ });
259+
260+ - name : " Close pull request"
261+ if : github.event_name == 'pull_request_target'
262+ run : |
263+ echo "::notice::Closing PR #$PR_NUMBER after successful Gerrit submission"
264+
265+ if [[ -n "${SET_ISSUE_ID:-}" ]]; then
266+ # Keep branch for issue tracking workflows
267+ gh pr close --comment "Auto-closed: Submitted to Gerrit" "$PR_NUMBER"
268+ else
269+ # Delete branch for cleaner repo
270+ gh pr close --comment "Auto-closed: Submitted to Gerrit" --delete-branch "$PR_NUMBER"
271+ fi
272+ env :
273+ GH_TOKEN : ${{ github.token }}
274+
275+ - name : " Workflow summary"
276+ if : always()
277+ run : |
278+ {
279+ echo "# GitHub2Gerrit Workflow Summary"
280+ echo ""
281+ echo "**PR Number:** $PR_NUMBER"
282+ echo "**Repository:** ${{ github.repository }}"
283+ echo "**Gerrit Server:** ${GERRIT_SERVER:-'Not set'}"
284+ echo "**Submission Mode:** ${{ inputs.SUBMIT_SINGLE_COMMITS == true && 'Individual commits' || 'Squashed commit' }}"
285+
286+ if [[ -n "${GERRIT_CHANGE_REQUEST_URL:-}" ]]; then
287+ echo ""
288+ echo "**✅ Success:** Changes submitted to Gerrit"
289+ echo "**Gerrit URL(s):** $GERRIT_CHANGE_REQUEST_URL"
290+ else
291+ echo ""
292+ echo "**❌ Status:** Workflow completed but no Gerrit URL available"
293+ fi
294+
295+ echo ""
296+ echo "**Timestamp:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
297+ } >> "$GITHUB_STEP_SUMMARY"
298+
299+ - name : " Set job outputs"
300+ if : env.GERRIT_CHANGE_REQUEST_URL != ''
301+ run : |
302+ echo "change_url=${GERRIT_CHANGE_REQUEST_URL}" >> "$GITHUB_OUTPUT"
303+ echo "change_number=${GERRIT_CHANGE_REQUEST_NUM}" >> "$GITHUB_OUTPUT"
0 commit comments