Skip to content

rfc(git-clone): add support for pull request and merge request urls #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
michaelbrewer opened this issue Apr 2, 2024 · 2 comments

Comments

@michaelbrewer
Copy link

michaelbrewer commented Apr 2, 2024

Overview

When building an "open in coder" workflow from any url, we could also support Github Pull Requests and Gitlab Merge Requests.

Notes on Pull Request

Neither can allow for pushes to go to the right branch

Github:

  • git fetch origin pull/<PR>/head:pr/<PR>; git switch pr/<PR>
  • git fetch origin merge-requests/<PR>/head; git switch FETCH_HEAD

eg:

git clone https://github.com/michaelbrewer/repo-tests.log.git
cd repo-tests.log
git fetch origin pull/1/head:pr/1
git switch pr/1

Gitlab:

  • git fetch origin merge-requests/<MR>/head:pr/<MR>; git switch pr/<MR>
  • git fetch origin merge-requests/<MR>/head; git checkout FETCH_HEAD

eg:

git clone https://gitlab.com/mike.brew/repo-tests.log.git
cd repo-tests.log
git fetch origin merge-requests/1/head:mr/1
git switch mr/1

So probably better to use the github / gitlab apis?

Using apis

To be able to support git push for a pull request, the most reliable way is to use the git providers api. We would need
to detect self-hosted git and find the relavant api endpoint ie: https://api.github.com/ becomes https://github.yourcompany.com/

Using the Github APIs:

We can setup the origin and upstream and get the correct branch name

#!/bin/bash
# Github Pull Request Cloning Script
# Example usage:
# export GITHUB_PAT=XXXX
# ./github-pr.sh https://github.com/coder/modules/pull/210
# ./github-pr.sh https://github.com/michaelbrewer/repo-tests.log/pull/1

url="$1"
owner=$(echo "$url" | cut -d'/' -f4)
repo=$(echo "$url" | cut -d'/' -f5)
pull_number=$(echo "$url" | cut -d'/' -f7)

output=$(curl -s -L \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer $GITHUB_PAT" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/"$owner"/"$repo"/pulls/"$pull_number")

name=$(echo "$output" | jq -r '.base.repo.name')
clone_url=$(echo "$output" | jq -r '.head.repo.clone_url')
branch_name=$(echo "$output" | jq -r '.head.ref')
upstream_url=$(echo "$output" | jq -r '.base.repo.clone_url')

git clone "$clone_url" -b "$branch_name" "$name"
cd "$name" || exit
git remote add upstream "$upstream_url"

Gitlab api

Gitlab version has to do 3 api calls and id is a best guess

#!/bin/bash
# Github Merge Request Cloning Script
#
# Example usage:
# GITLAB_PAT=XXXX
# ./gitlab-mr.sh https://gitlab.com/mike.brew/repo-tests.log/-/merge_requests/1

url="$1"
id=$(echo "$url" | cut -d'/' -f4,5 | sed 's/\//%2F/g')
merge_request_iid=$(echo "$url" | cut -d'/' -f8)

# Get the merge request details
# "GET /projects/$id/merge_requests/$merge_request_iid"
mr_output=$(curl -s -L \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $GITLAB_PAT" \
    https://gitlab.com/api/v4/projects/"$id"/merge_requests/"$merge_request_iid")

source_project_id=$(echo "$mr_output" | jq -r '.source_project_id')
target_project_id=$(echo "$mr_output" | jq -r '.target_project_id')

# Get the source project details
source_output=$(curl -s -L \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $GITLAB_PAT" \
    https://gitlab.com/api/v4/projects/"$source_project_id")

# Get the target project details
target_output=$(curl -s -L \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $GITLAB_PAT" \
    https://gitlab.com/api/v4/projects/"$target_project_id")

name=$(echo "$target_output" | jq -r '.name')
clone_url=$(echo "$source_output" | jq -r '.http_url_to_repo')
upstream_url=$(echo "$target_output" | jq -r '.http_url_to_repo')
branch_name=$(echo "$mr_output" | jq -r '.source_branch')

git clone "$clone_url" -b "$branch_name" "$name"
cd "$name" || exit
git remote add upstream "$upstream_url"

Using Bitbucket API

From Get a pull request

#!/bin/bash
# Bitbucket Pull Request Cloning Script
# Example usage:
# ./bitbucket-pr.sh https://bitbucket.org/gyftteam/repo-tests.log/pull-requests/1 

BITBUCKET_PAT="username:app_password"

url="$1"
workspace=$(echo "$url" | cut -d'/' -f4)
repo_slug=$(echo "$url" | cut -d'/' -f5)
pull_request_id=$(echo "$url" | cut -d'/' -f7)

# Get the pull request details
output=$(curl -s --request GET \
  --url "https://api.bitbucket.org/2.0/repositories/$workspace/$repo_slug/pullrequests/$pull_request_id" \
  --header "Authorization: Basic $(echo -n $BITBUCKET_PAT | base64)" \
  --header 'Accept: application/json')

# Get the source repo details
source_respotory_links_self=$(echo "$output" | jq -r '.source.repository.links.self.href')
source_output=$(curl -s --request GET \
  --url "$source_respotory_links_self" \
  --header "Authorization Basic $(echo -n $BITBUCKET_PAT | base64)" \
    --header 'Accept: application/json')

# Get the target repo details
destination_respotory_links_self=$(echo "$output" | jq -r '.destination.repository.links.self.href')
destination_output=$(curl -s --request GET \
  --url "$destination_respotory_links_self" \
  --header "Authorization Basic $(echo -n $BITBUCKET_PAT | base64)" \
    --header 'Accept: application/json')

name=$(echo "$output" | jq -r '.source.repository.name')
clone_url=$(echo "$source_output" | jq -r '.links.clone[] | select(.name == "https") | .href')
branch_name=$(echo "$output" | jq -r '.source.branch.name')
upstream_url=$(echo "$destination_output" | jq -r '.links.clone[] | select(.name == "https") | .href')

git clone "$clone_url" -b "$branch_name" "$name"
cd "$name" || exit
git remote add upstream "$upstream_url"
@michaelbrewer michaelbrewer changed the title Feat(git-clone): add support for pull request and merge request urls feat(git-clone): add support for pull request and merge request urls Apr 2, 2024
@michaelbrewer michaelbrewer changed the title feat(git-clone): add support for pull request and merge request urls rfc(git-clone): add support for pull request and merge request urls Apr 17, 2024
@michaelbrewer
Copy link
Author

going to put time ahead for this soon and start with Gitlab first.

1 similar comment
@michaelbrewer

This comment was marked as duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant