Skip to content

Commit

Permalink
Fix: Refactor code to incorporate review comments
Browse files Browse the repository at this point in the history
- Remove path and checkout repo at root level
- rm ssh-user input while cloning repository
- Introduce the fetch-depth as a input param by caller
- Set env reading .gitreview file
- Remove explicity git remote add gerrit
- Update documentation and examples accordingly

Signed-off-by: Anil Belur <abelur@linuxfoundation.org>
  • Loading branch information
askb committed Jul 19, 2024
1 parent 514b7b3 commit 23779cb
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 101 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/call-g2g-composite-action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2024 The Linux Foundation <abelur@linux.com>

# Calls the github2gerrit composite action.
name: call-github2gerrit-composite-action

# yamllint disable-line rule:truthy
Expand All @@ -27,9 +28,10 @@ jobs:
id: gerrit-upload
uses: askb/github2gerrit@main
with:
FETCH_DEPTH: 10
GERRIT_KNOWN_HOSTS: ${{ vars.GERRIT_KNOWN_HOSTS }}
GERRIT_PROJECT: ${{ vars.GERRIT_PROJECT }}
GERRIT_SERVER: ${{ vars.GERRIT_SERVER }}
GERRIT_SERVER_PORT: "29418"
GERRIT_SSH_PRIVKEY_G2G: ${{ secrets.GERRIT_SSH_PRIVKEY_G2G }}
GERRIT_SSH_USER_G2G: ${{ vars.GERRIT_SSH_USER_G2G }}
GERRIT_SSH_USER_G2G_EMAIL: ${{ vars.GERRIT_SSH_USER_G2G_EMAIL }}
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/call-g2g-reusable-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2024 The Linux Foundation <abelur@linux.com>

# Calls the github2gerrit reusable workflow
name: call-github2gerrit-reusable-workflow

# yamllint disable-line rule:truthy
Expand All @@ -27,8 +28,6 @@ jobs:
uses: askb/github2gerrit/.github/workflows/github2gerrit.yaml@main
with:
GERRIT_KNOWN_HOSTS: ${{ vars.GERRIT_KNOWN_HOSTS }}
GERRIT_PROJECT: ${{ vars.GERRIT_PROJECT }}
GERRIT_SERVER: ${{ vars.GERRIT_SERVER }}
GERRIT_SSH_USER_G2G: ${{ vars.GERRIT_SSH_USER_G2G }}
GERRIT_SSH_USER_G2G_EMAIL: ${{ vars.GERRIT_SSH_USER_G2G_EMAIL }}
ORGANIZATION: ${{ vars.ORGANIZATION }}
Expand Down
122 changes: 84 additions & 38 deletions .github/workflows/github2gerrit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,29 @@ name: github2gerrit-reusable-workflow
on:
workflow_call:
inputs:
FETCH_DEPTH:
description: "fetch-depth for the clone. (Default: 10)"
required: false
default: "10"
type: string
GERRIT_KNOWN_HOSTS:
description: "known hosts"
required: true
type: string
GERRIT_SERVER:
description: "Gerrit hostname ex: git.opendaylight.org"
required: true
required: false
default: ""
type: string
GERRIT_SERVER_PORT:
description: "Gerrit port. (Default: 29418)"
required: false
default: "29418"
type: string
GERRIT_PROJECT:
description: "Gerrit project name. ex: releng/builder"
required: true
required: false
default: ""
type: string
GERRIT_SSH_USER_G2G:
description: "Gerrit user-id for SSH"
Expand All @@ -38,7 +50,7 @@ on:
type: string
secrets:
GERRIT_SSH_PRIVKEY_G2G:
description: "priv key"
description: "SSH Private key"
required: true

concurrency:
Expand All @@ -64,38 +76,83 @@ jobs:
git review --version
jq --version
- name: Set env with Gerrit Github repo format
- name: Clone Github repo where the PR is submitted
uses: actions/checkout@v4
with:
fetch-depth: ${{ inputs.fetch_depth }}
ref: ${{ github.event.pull_request.head.sha }}

- name: "Read inputs to set PROJECT_REPO_{GERRIT,GITHUB} if .gitreview is undefined"
if: ${{ hashFiles('.gitreview') == '' }}
shell: bash
run: |
set -x
project_repo_github="${{ github.repository }}"
# change any '-' to '/' and remove owner name
project_repo_github="${project_repo_github#*/}"
project_repo_gerrit="${project_repo_github//-//}"
if [[ ${{ inputs.GERRIT_PROJECT }} != "$project_repo_github" ]]; then
# remove repo owner name
project_repo_github="${project_repo_github#*/}"
# change any '-' to '/' and
project_repo_gerrit="${project_repo_github//-//}"
echo "PROJECT_REPO_GITHUB=${project_repo_github}" >> "$GITHUB_ENV"
echo "PROJECT_REPO_GERRIT=${project_repo_gerrit}" >> "$GITHUB_ENV"
fi
- name: Read .gitreview to set PROJECT_REPO_GERRIT & PROJECT_REPO_GITHUB
if: ${{ hashFiles('.gitreview') != '' }}
shell: bash
# yamllint disable rule:line-length
run: |
set -x
project_repo_gerrit_git=$(grep -E "project" .gitreview | cut -d "=" -f2)
# strip .git suffix
project_repo_gerrit="${project_repo_gerrit_git//.*}"
# change any '/' to '-' nested repos are not available on Github
project_repo_github="${project_repo_gerrit////-}"
echo "PROJECT_REPO_GERRIT=${project_repo_gerrit}" >> "$GITHUB_ENV"
echo "PROJECT_REPO_GITHUB=${project_repo_github}" >> "$GITHUB_ENV"
- name: Read .gitreview and set env GERRIT_SERVER and GERRIT_PORT
if: ${{ hashFiles('.gitreview') != '' }}
shell: bash
# yamllint disable rule:line-length
run: |
set -x
gerrit_server=$(grep -E "host" .gitreview | cut -d "=" -f2)
gerrit_server_port=$(grep -E "port" .gitreview | cut -d "=" -f2)
echo "GERRIT_SERVER=${gerrit_server}" >> "$GITHUB_ENV"
echo "GERRIT_SERVER_PORT=${gerrit_server_port}" >> "$GITHUB_ENV"
- name: Set GERRIT_SERVER and GERRIT_PORT when .gitreview is undefined
if: ${{ hashFiles('.gitreview') == '' }}
shell: bash
# yamllint disable rule:line-length
run: |
set -x
if [[ ${{ inputs.GERRIT_SERVER }} != '' ]]; then
echo "GERRIT_SERVER=${{ inputs.GERRIT_SERVER }}" >> "$GITHUB_ENV"
fi
if [[ ${{ inputs.GERRIT_SERVER_PORT }} != '' ]]; then
echo "GERRIT_SERVER_PORT=${{ inputs.GERRIT_SERVER_PORT }}" >> "$GITHUB_ENV"
fi
- name: Set env GITHUB branch in env
shell: bash
run: |
gerrit_branch="${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
echo "GERRIT_BRANCH=${gerrit_branch}" >> "$GITHUB_ENV"
- name: Clone Github repo where the PR is submitted
uses: actions/checkout@v4
with:
ssh-user: ${{ inputs.GERRIT_SSH_USER_G2G }}
path: "${{ env.PROJECT_REPO_GITHUB }}-${{ env.GERRIT_BRANCH }}"
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: Print last X commits in the git log
if: env.ACT == 'true'
shell: bash
# yamllint disable rule:line-length
run: |
set -x
cd "$GITHUB_WORKSPACE/${{ env.PROJECT_REPO_GITHUB }}-${{ env.GERRIT_BRANCH }}"
git --no-pager log --graph --all --decorate --pretty=oneline -n5
- name: Install SSH Key
Expand All @@ -105,7 +162,7 @@ jobs:
name: "id_rsa"
known_hosts: ${{ inputs.GERRIT_KNOWN_HOSTS }}
config: |
Host ${{ inputs.GERRIT_SERVER }}
Host ${{ env.GERRIT_SERVER }}
User ${{ inputs.GERRIT_SSH_USER_G2G }}
Port 29418
PubkeyAcceptedKeyTypes +ssh-rsa
Expand All @@ -118,23 +175,19 @@ jobs:
run: |
set -x
# Query for a pre-existing gerrit review
cd "$GITHUB_WORKSPACE/${{ env.PROJECT_REPO_GITHUB }}-${{ env.GERRIT_BRANCH }}"
# Setup global git config required by git-review
git config --global gitreview.username ${{ inputs.GERRIT_SSH_USER_G2G }}
git config --global user.name ${{ inputs.GERRIT_SSH_USER_G2G }}
git config --global user.email ${{ inputs.GERRIT_SSH_USER_G2G_EMAIL }}
# Add Gerrit remote and print remote settings
git remote add gerrit ssh://${{ inputs.GERRIT_SSH_USER_G2G }}@${{ inputs.GERRIT_SERVER }}:29418/${{ env.PROJECT_REPO_GERRIT }}.git
git remote -v
# Workaround for git-review failing to copy the commit-msg hook to submodules
git config core.hooksPath "$(git rev-parse --show-toplevel)/.git/hooks"
# Init gerrit repo
git review -s -v
# print remote settings
git remote -v
- name: Extract pull-request number
shell: bash
# yamllint disable rule:line-length
Expand All @@ -149,20 +202,18 @@ jobs:
# yamllint disable rule:line-length
run: |
set -x
cd "$GITHUB_WORKSPACE/${{ env.PROJECT_REPO_GITHUB }}-${{ env.GERRIT_BRANCH }}"
num_commits="$(gh pr view ${{ env.PR_NUMBER }} --json commits | jq '.[] | length')"
echo "PR_COMMITS=$num_commits" >> "$GITHUB_ENV"
env:
GH_TOKEN: ${{ github.token }}

- name: Apply patch on local repo
- name: Squash commits into a single commit
shell: bash
if: ${{ (env.PR_COMMITS > 0) }}
# yamllint disable rule:line-length
run: |
set -x
cd "$GITHUB_WORKSPACE/${{ env.PROJECT_REPO_GITHUB }}-${{ env.GERRIT_BRANCH }}"
git --no-pager log --graph --all --decorate --pretty=oneline -n"${{ env.PR_COMMITS }}"
# Create a Change-id from all the PR
Expand All @@ -171,17 +222,17 @@ jobs:
# Check if change-id is present in each commit and use the first one
# Capture and check for signed-of-by and Change-Id
git log -v --format=%B --reverse "HEAD..HEAD@{1}" | grep -E "^(Change-Id)" > change-ID.txt || true
git log -v --format=%B --reverse "HEAD..HEAD@{1}" | grep -E "^(Change-Id)" > change-Id.txt || true
git log -v --format=%B --reverse "HEAD..HEAD@{1}" | grep -E "^(Signed-off-by)" > signed-off-by.txt || true
git log -v --format=%B --reverse "HEAD..HEAD@{1}" | grep -Ev "^(Signed-off-by|Change-Id)" > commit-msg.txt
if [[ -f commit-msg.txt ]]; then
commit_message="${commit_message:-commit-msg.txt}"
fi
if [[ -f change-ID.txt ]]; then
if [[ -f change-Id.txt ]]; then
commit_message+=' '
commit_message+="change-ID.txt"
commit_message+="change-Id.txt"
fi
if [[ -f signed-off-by.txt ]]; then
Expand All @@ -194,17 +245,13 @@ jobs:
git commit -s -v --no-edit -m "$(cat $commit_message)"
git log -n2
# TODO: Get rid of any merge commit in the patch
# TODO: process each commit one at a time in a loop: foreach or iterate
- name: Submit the change to Gerrit repository
id: submit
if: env.PR_NUMBER != ''
shell: bash
# yamllint disable rule:line-length
run: |
set -x
cd "$GITHUB_WORKSPACE/${{ env.PROJECT_REPO_GITHUB }}-${{ env.GERRIT_BRANCH }}"
reviewers_emails_list="${{ inputs.REVIEWERS_EMAIL }}"
# If the reviewers email is unset/empty then use a default
Expand All @@ -229,7 +276,7 @@ jobs:
set -x
# Query for a pre-existing gerrit review to retrive Change-Id
ssh -v -p 29418 "${{ inputs.GERRIT_SSH_USER_G2G }}@${{ inputs.GERRIT_SERVER }}" \
ssh -v -p 29418 "${{ inputs.GERRIT_SSH_USER_G2G }}@${{ env.GERRIT_SERVER }}" \
gerrit query limit:1 owner:self is:open \
project:"${{ env.PROJECT_REPO_GERRIT }}" \
--current-patch-set --format=JSON \
Expand All @@ -249,7 +296,7 @@ jobs:
retries: 3
retry-exempt-status-codes: 400,401
script: |
const output = `The pull-request PR-${{ env.PR_NUMBER }} is submitted to Gerrit [${{ vars.ORGANIZATION }}](https://${{ inputs.GERRIT_SERVER }})! \n
const output = `The pull-request PR-${{ env.PR_NUMBER }} is submitted to Gerrit [${{ vars.ORGANIZATION }}](https://${{ env.GERRIT_SERVER }})! \n
To follow up on the change visit: [${{ env.GERRIT_CHANGE_REQUEST_NUMBER }}](${{ env.GERRIT_CHANGE_REQUEST_URL }}) \n \n
NOTE: The pull-request PR-${{ env.PR_NUMBER }} will be closed, re-opening the pull-request will not update the same commit and may result in duplicate changes on Gerrit.`
github.rest.issues.createComment({
Expand All @@ -265,7 +312,6 @@ jobs:
# yamllint disable rule:line-length
run: |
set -x
cd "$GITHUB_WORKSPACE/${{ env.PROJECT_REPO_GITHUB }}-${{ env.GERRIT_BRANCH }}"
gh pr close --comment "Auto-closing pull request" --delete-branch "${{ env.PR_NUMBER }}"
env:
GH_TOKEN: ${{ github.token }}
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# github2gerrit github action
# github2gerrit action

This action extracts the commits from a GitHub pull request and submits them to an upstream Gerrit repository. It allows GitHub developers to contribute to Gerrit-based repositories that are primarily developed on Gerrit servers and replicated onto GitHub.
The action extracts the commits from a GitHub pull-request and submits them to an upstream Gerrit repository. This allows GitHub developers to contribute to Gerrit-based repositories that are primarily maintained on Gerrit servers and replicated onto GitHub.

## Pre-requisites

1. GitHub replication is set up on the Gerrit repository over SSH. Refer to the [Gerrit replication configuration setup guide](https://docs.releng.linuxfoundation.org/en/latest/infra/gerrit.html) maintained by the Linux Foundation release engineering team.
1. GitHub replication is set up on the Gerrit repository over SSH. Refer to the [Gerrit replication configuration setup guide](https://docs.releng.linuxfoundation.org/en/latest/infra/gerrit.html) maintained by the Linux Foundation release engineering team. This also requires creating ssh-keypair
and [registering the SSH keys](https://docs.releng.linuxfoundation.org/en/latest/gerrit.html#register-key-gerrit) with Gerrit.
2. Create a user account on GitHub with permissions to submit changes to Gerrit and ensure it is added to the GitHub organization or repository as a member.
3. Use a [.gitreview](https://docs.opendev.org/opendev/git-review/latest/installation.html#gitreview-file-format) file point to the Gerrit server and repository. If this not alternatively pass the GERRIT_SERVER or GERRIT_PROJECT as inputs to the workflow.

## How the Action Works

The action and workflow are written in Bash scripting, Git, and git-review.
The action and workflow are written with bash scripts using well known Git SCM tools, gh, jq and git-review.

1. The action is triggered when a new pull request is created on a GitHub repository configured with the action.
2. Squash all the commits in the pull request into a single commit.
Expand All @@ -25,15 +27,17 @@ The action and workflow are written in Bash scripting, Git, and git-review.
## Required Inputs

- `GERRIT_KNOWN_HOSTS`: Known host of the Gerrit repository.
- `GERRIT_PROJECT`: Gerrit project repository.
- `GERRIT_SERVER`: Gerrit server FQDN.
- `GERRIT_SSH_PRIVKEY_G2G`: SSH private key pair (The private key has to be added to the Gerrit user's account settings. Gerrit -> User Settings).
- `GERRIT_SSH_USER_G2G`: Gerrit server username (Required to connect to Gerrit).
- `GERRIT_SSH_USER_G2G_EMAIL`: Email of the Gerrit user.

## Optional Inputs

- `ORGANIZATION`: The GitHub organization or project.
- `FETCH_DEPTH`: fetch-depth of the clone repo. (Default: 10)
- `GERRIT_PROJECT`: Gerrit project repository (Default read from .gitreview).
- `GERRIT_SERVER`: Gerrit server FQDN (Default read from .gitreview).
- `GERRIT_SERVER_PORT`: Gerrit server port (Default: 29418)
- `ORGANIZATION`: The GitHub Organization or Project.
- `REVIEWER_EMAIL`: Committers' email list (comma-separated list without spaces).

## Full Example Usage with Composite Action
Expand Down Expand Up @@ -69,9 +73,10 @@ jobs:
id: gerrit-upload
uses: askb/github2gerrit@main
with:
FETCH_DEPTH: 10
GERRIT_KNOWN_HOSTS: ${{ vars.GERRIT_KNOWN_HOSTS }}
GERRIT_PROJECT: ${{ vars.GERRIT_PROJECT }}
GERRIT_SERVER: ${{ vars.GERRIT_SERVER }}
GERRIT_SERVER_PORT: "29418"
GERRIT_SSH_PRIVKEY_G2G: ${{ secrets.GERRIT_SSH_PRIVKEY_G2G }}
GERRIT_SSH_USER_G2G: ${{ vars.GERRIT_SSH_USER_G2G }}
GERRIT_SSH_USER_G2G_EMAIL: ${{ vars.GERRIT_SSH_USER_G2G_EMAIL }}
Expand Down Expand Up @@ -118,8 +123,6 @@ jobs:
uses: askb/github2gerrit/.github/workflows/github2gerrit.yaml@main
with:
GERRIT_KNOWN_HOSTS: ${{ vars.GERRIT_KNOWN_HOSTS }}
GERRIT_PROJECT: ${{ vars.GERRIT_PROJECT }}
GERRIT_SERVER: ${{ vars.GERRIT_SERVER }}
GERRIT_SSH_USER_G2G: ${{ vars.GERRIT_SSH_USER_G2G }}
GERRIT_SSH_USER_G2G_EMAIL: ${{ vars.GERRIT_SSH_USER_G2G_EMAIL }}
ORGANIZATION: ${{ vars.ORGANIZATION }}
Expand Down
Loading

0 comments on commit 23779cb

Please sign in to comment.