Skip to content
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

Use git configuration #10

Merged
merged 2 commits into from
May 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
name: Tests

on: [push, pull_request]
on:
pull_request:
branches:
- master
paths-ignore:
- 'completion/**'
- 'doc/**'
- 'git-mr-completion.bash'
- 'LICENSE'
- 'README.md'
push:
branches:
- master
paths-ignore:
- 'completion/**'
- 'doc/**'
- 'git-mr-completion.bash'
- 'LICENSE'
- 'README.md'

jobs:

Expand Down
112 changes: 85 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,58 +160,116 @@ Completion functions for Bash and Zsh are available:

### Configuration

You need to configure the following environment variables:
Git-mr can either be configured through [git-config](https://git-scm.com/docs/git-config) or environment variables.

When using Git configuration, project-specific overrides can be set by omitting the `--global` option:
```bash
export JIRA_USER="user.name@mycompany.com"
# Global configuration stored in your ~/.gitconfig
git config --global mr.global-option "global-value"

# Local configuration stored in current project's .git/config
git config mr.local-option "local-value"
```

Environment variables take precedence over Git configuration.

#### Git configuration reference

```bash
# Required configuration -------------------------------------------------------

git config --global mr.jira-instance "mycompany.atlassian.net"
git config --global mr.jira-user "user.name@mycompany.com"
git config --global mr.jira-token "abcdefghijklmnopqrstuvwx"

git config --global mr.jira-code-pattern "[A-Z]{2,3}-[0-9]+"

git config --global mr.gitlab-domain "myapp.gitlab.com"
git config --global mr.gitlab-token "Zyxwvutsrqponmlkjihg"

# Optional configuration -------------------------------------------------------

# Default labels for new merge requests
git config --global mr.gitlab-default-labels "Review,My Team"

# Check "Delete source branch" by default (defaults to 1)
# git config --global mr.gitlab-remove-source-branch-on-merge 1

# Gitlab status labels (comma-separated, without spaces in between)
git config --global mr.gitlab-ip-labels "WIP"
git config --global mr.gitlab-cr-labels "Review"
git config --global mr.gitlab-qa-labels "Testing"
git config --global mr.gitlab-ok-labels "Accepted"

# Jira status - transition IDs
git config --global mr.jira-ip-id "xx"
git config --global mr.jira-cr-id "xx"
git config --global mr.jira-qa-id "xx"
git config --global mr.jira-ok-id "xx"

# Always use extended commit messages
# git config --global mr.git-mr-extended 1

# Required upvote count to turn indicator green in `mr status` (defaults to 2)
# git config --global mr.git-mr-required-upvotes 2

# Network timeout (in seconds, defaults to 5)
# git config --global mr.git-mr-timeout 5
```

#### Environment variables reference

```bash
# Required configuration -------------------------------------------------------

export JIRA_INSTANCE="mycompany.atlassian.net"
export JIRA_USER="user.name@mycompany.com"
export JIRA_TOKEN="abcdefghijklmnopqrstuvwx"

export JIRA_CODE_PATTERN="[A-Z]{2,3}-[0-9]+"

export GITLAB_DOMAIN="myapp.gitlab.com"
export GITLAB_TOKEN="Zyxwvutsrqponmlkjihg"
```

To create a Jira API Token, go to:
* https://id.atlassian.com/manage-profile/security/api-tokens
(Account Settings -> Security -> API Token -> Create and manage API tokens)

To create a Gitlab API Token, go to:
* https://myapp.gitlab.com/-/profile/personal_access_tokens?name=Git-MR+Access+token&scopes=api
(Settings -> Access Tokens)
# Optional configuration -------------------------------------------------------

Other optional configuration variables:
```bash
# Default labels for new merge requests
export GITLAB_DEFAULT_LABELS="Review,My Team"

# Check "Delete source branch" by default (defaults to 1)
#export GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE=1

# Gitlab status labels (comma-separated, without spaces in between)
export GITLAB_IP_LABELS="WIP" # Label(s) set on "In Progress" step
export GITLAB_CR_LABELS="Review" # Label(s) set on "Code Review" step
export GITLAB_QA_LABELS="Testing" # Label(s) set on "Quality Assurance" step
export GITLAB_OK_LABELS="Accepted" # Label(s) set on "Accepted" step
export GITLAB_IP_LABELS="WIP"
export GITLAB_CR_LABELS="Review"
export GITLAB_QA_LABELS="Testing"
export GITLAB_OK_LABELS="Accepted"

# Jira status - transition IDs
export JIRA_IP_ID="xx" # "In progress" transition ID
export JIRA_CR_ID="xx" # "Code review" transition ID
export JIRA_QA_ID="xx" # "Quality Assurance" transition ID
export JIRA_OK_ID="xx" # "Accepted" transition ID
export JIRA_IP_ID="xx"
export JIRA_CR_ID="xx"
export JIRA_QA_ID="xx"
export JIRA_OK_ID="xx"

# Always use extended commit messages
# export GIT_MR_EXTENDED=1

# Required upvote count to turn indicator green in `mr status` (defaults to 2)
#export GIT_MR_REQUIRED_UPVOTES=2

# Number of description lines shown in `mr menu update` (defaults to 15)
#export GIT_MR_MENU_UPDATE_CONTEXT_LINES=15

# Check "Delete source branch" by default (defaults to 1)
#export GITLAB_DEFAULT_FORCE_REMOVE_SOURCE_BRANCH=1

# Network timeout (in seconds, defaults to 5)
#export GIT_MR_TIMEOUT=5
```

#### Jira & Gitlab tokens

To create a Jira API Token, go to:
* https://id.atlassian.com/manage-profile/security/api-tokens
(Account Settings -> Security -> API Token -> Create and manage API tokens)

To create a Gitlab API Token, go to:
* https://myapp.gitlab.com/-/profile/personal_access_tokens?name=Git-MR+Access+token&scopes=api
(Settings -> Access Tokens)

## Commands

Expand All @@ -231,7 +289,7 @@ This will print a merge request description, with a link to Jira ticket and curr
If a merge request based on the current branch is found on Gitlab, its URL will be provided, along with current votes, open and resolved threads and mergeable status.
Otherwise, a link to create a new merge request will be provided.

Default labels and "Delete source branch" status can be configured with the `GITLAB_DEFAULT_LABELS` and `GITLAB_DEFAULT_FORCE_REMOVE_SOURCE_BRANCH` environment variables.
Default labels and "Delete source branch" status can be configured with the `GITLAB_DEFAULT_LABELS` and `GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE` environment variables.

![git mr](doc/git-mr.png)

Expand Down
127 changes: 77 additions & 50 deletions git-mr
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ jira_request() {
-H "Authorization: Basic ${auth_token}" \
-H "Content-Type: application/json" \
--data "${request_data}" \
--max-time "${GIT_MR_TIMEOUT:-5}" \
--max-time "${GIT_MR_TIMEOUT}" \
"${jira_base_url}/${request_url}" || exit_error "$ERR_JIRA_API" "Jira request error"
}

Expand Down Expand Up @@ -626,7 +626,7 @@ gitlab_request() {
-H "Private-Token: ${GITLAB_TOKEN}" \
-H "Content-Type: application/json" \
--data "${request_data}" \
--max-time "${GIT_MR_TIMEOUT:-5}" \
--max-time "${GIT_MR_TIMEOUT}" \
"${gitlab_base_url}/${request_url}") || exit_error "$ERR_GITLAB_API" "Gitlab request error"

if [[ $request_verb != "GET" ]]; then
Expand Down Expand Up @@ -677,7 +677,7 @@ gitlab_new_merge_request_url() {
done

# other options
if [[ "${GITLAB_DEFAULT_FORCE_REMOVE_SOURCE_BRANCH:-1}" -eq 1 ]]; then
if [[ "${GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE}" -eq 1 ]]; then
gitlab_mr_url="${gitlab_mr_url}&$(urlencode "merge_request[force_remove_source_branch]")=1"
fi

Expand Down Expand Up @@ -883,7 +883,7 @@ gitlab_merge_request_merge() {

local mr_iid=$1; [[ -n $mr_iid ]] || exit_error "$ERR_MR" "No mr_iid provided"

gitlab_current_project_request "merge_requests/${mr_iid}/merge?should_remove_source_branch=${GITLAB_DEFAULT_FORCE_REMOVE_SOURCE_BRANCH:-1}" "PUT"
gitlab_current_project_request "merge_requests/${mr_iid}/merge?should_remove_source_branch=${GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE}" "PUT"
}

gitlab_title_is_draft() {
Expand Down Expand Up @@ -1157,9 +1157,9 @@ mr_print_status() {
local labels_str_len=$((${#labels} + $((labels_count * 2)) + 4)) # 2 spaces + 2 for larger icon

# Votes
if [[ $upvotes -ge ${GIT_MR_REQUIRED_UPVOTES:-2} ]]; then upvotes=$(colorize "$upvotes" "bold" "lightgreen")
elif [[ $upvotes -gt 0 ]]; then upvotes=$(colorize "$upvotes" "bold" "lightyellow")
else upvotes=$(colorize "$upvotes" "bold"); fi
if [[ $upvotes -ge ${GIT_MR_REQUIRED_UPVOTES} ]]; then upvotes=$(colorize "$upvotes" "bold" "lightgreen")
elif [[ $upvotes -gt 0 ]]; then upvotes=$(colorize "$upvotes" "bold" "lightyellow")
else upvotes=$(colorize "$upvotes" "bold"); fi

if [[ $downvotes -gt 0 ]];
then downvotes=$(colorize "$downvotes" "bold" "lightred")
Expand Down Expand Up @@ -2578,54 +2578,47 @@ ${b}CONFIGURATION${r}
EOF
if [[ $GIT_MR_VERBOSE -eq 1 ]]; then
cat <<EOF
You need to configure the following environment variables:

export JIRA_USER="user.name@mycompany.com"
export JIRA_INSTANCE="mycompany.atlassian.net"
export JIRA_TOKEN="abcdefghijklmnopqrstuvwx"
export JIRA_CODE_PATTERN="[A-Z]{2,3}-[0-9]+"

export GITLAB_DOMAIN="myapp.gitlab.com"
export GITLAB_TOKEN="Zyxwvutsrqponmlkjihg"
Configuration reference:

+---------------------------------------------+---------------------------------------+
| ${b}git configuration${r} (${i} git config [--global]${r} ) | ${b}environment variables${r} |
+---------------------------------------------+---------------------------------------+
| mr.jira-instance | JIRA_INSTANCE |
| mr.jira-user | JIRA_USER |
| mr.jira-token | JIRA_TOKEN |
| mr.jira-code-pattern | JIRA_CODE_PATTERN |
| | |
| mr.gitlab-domain | GITLAB_DOMAIN |
| mr.gitlab-token | GITLAB_TOKEN |
+---------------------------------------------+---------------------------------------+
| mr.gitlab-default-labels | GITLAB_DEFAULT_LABELS |
| | |
| mr.gitlab-ip-labels | GITLAB_IP_LABELS |
| mr.gitlab-cr-labels | GITLAB_CR_LABELS |
| mr.gitlab-qa-labels | GITLAB_QA_LABELS |
| mr.gitlab-ok-labels | GITLAB_OK_LABELS |
| | |
| mr.gitlab-remove-source-branch-on-merge | GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE |
| | |
| mr.jira-ip-id | JIRA_IP_ID |
| mr.jira-cr-id | JIRA_CR_ID |
| mr.jira-qa-id | JIRA_QA_ID |
| mr.jira-ok-id | JIRA_OK_ID |
| | |
| mr.git-mr-extended | GIT_MR_EXTENDED |
| | |
| mr.git-mr-required-upvotes | GIT_MR_REQUIRED_UPVOTES |
| | |
| mr.git-mr-timeout | GIT_MR_TIMEOUT |
+---------------------------------------------+---------------------------------------+

To create a Jira API Token, go to: https://id.atlassian.com/manage-profile/security/api-tokens
(Account Settings -> Security -> API Token -> Create and manage API tokens)

To create a Gitlab API Token, go to: https://myapp.gitlab.com/-/profile/personal_access_tokens?name=Git-MR+Access+token&scopes=api
(Settings -> Access Tokens)

Optional configuration variables:

# Default labels for new merge requests
export GITLAB_DEFAULT_LABELS="Review,My Team"

# Gitlab status labels (comma-separated, without spaces in between)
export GITLAB_IP_LABELS="WIP" # Label(s) set on "In Progress" step
export GITLAB_CR_LABELS="Review" # Label(s) set on "Code Review" step
export GITLAB_QA_LABELS="Testing" # Label(s) set on "Quality Assurance" step
export GITLAB_OK_LABELS="Validated" # Label(s) set on "Accepted" step

# Jira status - transition IDs
export JIRA_IP_ID="xx" # "In Progress" transition ID
export JIRA_CR_ID="xx" # "Code Review" transition ID
export JIRA_QA_ID="xx" # "Quality Assurance" transition ID
export JIRA_OK_ID="xx" # "Accepted" transition ID

# Always use extended commit messages
# export GIT_MR_EXTENDED=1

# Required upvote count to turn indicator green in \`mr status\` (defaults to 2)
#export GIT_MR_REQUIRED_UPVOTES=2

# Number of description lines shown in \`mr menu update\` (defaults to 15)
#export GIT_MR_MENU_UPDATE_CONTEXT_LINES=15

# Check "Delete source branch" by default (defaults to 1)
#export GITLAB_DEFAULT_FORCE_REMOVE_SOURCE_BRANCH=1

# Network timeout (in seconds, defaults to 5)
#export GIT_MR_TIMEOUT=5

EOF
else
cat <<EOF
Expand Down Expand Up @@ -2668,13 +2661,47 @@ GIT_MR_MENU_START=${GIT_MR_MENU_START:-"## Menu"}
GIT_MR_MENU_END=${GIT_MR_MENU_END:-"--------------------------------------------------------------------------------"}
GIT_MR_MENU_UPDATE_CONTEXT_LINES=${GIT_MR_MENU_UPDATE_CONTEXT_LINES:-15}

# Defaults
GIT_MR_REQUIRED_UPVOTES=${GIT_MR_REQUIRED_UPVOTES:-2}

# Custom file descriptors
git_mr_fd_mr=${GIT_MR_FD_MR=}
git_mr_fd_th=${GIT_MR_FD_TH=}


################################################################################
# Variables

JIRA_INSTANCE=${JIRA_INSTANCE:-$(git config --get mr.jira-instance || true)}
JIRA_USER=${JIRA_USER:-$( git config --get mr.jira-user || true)}
JIRA_TOKEN=${JIRA_TOKEN:-$( git config --get mr.jira-token || true)}

GITLAB_DOMAIN=${GITLAB_DOMAIN:-$(git config --get mr.gitlab-domain || true)}
GITLAB_TOKEN=${GITLAB_TOKEN:-$( git config --get mr.gitlab-token || true)}

JIRA_CODE_PATTERN=${JIRA_CODE_PATTERN:-$(git config --get mr.jira-code-pattern || true)}

JIRA_IP_ID=${JIRA_IP_ID:-$(git config --get mr.jira-ip-id || true)}
JIRA_CR_ID=${JIRA_CR_ID:-$(git config --get mr.jira-cr-id || true)}
JIRA_QA_ID=${JIRA_QA_ID:-$(git config --get mr.jira-qa-id || true)}
JIRA_OK_ID=${JIRA_OK_ID:-$(git config --get mr.jira-ok-id || true)}

GITLAB_IP_LABELS=${GITLAB_IP_LABELS-$(git config --get mr.gitlab-ip-labels || true)}
GITLAB_CR_LABELS=${GITLAB_CR_LABELS-$(git config --get mr.gitlab-cr-labels || true)}
GITLAB_QA_LABELS=${GITLAB_QA_LABELS-$(git config --get mr.gitlab-qa-labels || true)}
GITLAB_OK_LABELS=${GITLAB_OK_LABELS-$(git config --get mr.gitlab-ok-labels || true)}

GITLAB_DEFAULT_LABELS=${GITLAB_DEFAULT_LABELS-$(git config --get mr.gitlab-default-labels || true)}

GIT_MR_EXTENDED=${GIT_MR_EXTENDED-$(git config --get mr.git-mr-extended || true)}

GIT_MR_REQUIRED_UPVOTES=${GIT_MR_REQUIRED_UPVOTES:-$(git config --get mr.git-mr-required-upvotes || true)}
GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE=${GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE:-$(git config --get mr.gitlab-remove-source-branch-on-merge || true)}
GIT_MR_TIMEOUT=${GIT_MR_TIMEOUT:-$(git config --get mr.git-mr-timeout || true)}

# Defaults
GIT_MR_REQUIRED_UPVOTES=${GIT_MR_REQUIRED_UPVOTES:-2}
GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE=${GITLAB_REMOVE_SOURCE_BRANCH_ON_MERGE:-1}
GIT_MR_TIMEOUT=${GIT_MR_TIMEOUT:-5}


################################################################################
# Run

Expand Down
11 changes: 7 additions & 4 deletions hooks/prepare-commit-msg
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
# When on a branch referring to a Jira issue,
# ensure commit messages start with the issue reference

default_pattern="[A-Z]{2}-[0-9]+"
jira_code_pattern="${JIRA_CODE_PATTERN:-$default_pattern}"
JIRA_CODE_PATTERN=${JIRA_CODE_PATTERN:-$(git config --get mr.jira-code-pattern)}
if [ -z "$JIRA_CODE_PATTERN" ]; then
echo "JIRA_CODE_PATTERN not set - unable to guess issue code" >&2
exit 0
fi

current_branch=$(git rev-parse --abbrev-ref HEAD)
issue_code=$(echo "${current_branch}" | grep -Eo "$jira_code_pattern" | tail -n1)
issue_code=$(echo "${current_branch}" | grep -Eo "$JIRA_CODE_PATTERN" | tail -n1)
[ -n "$issue_code" ] || exit 0 # No issue code detected

current_msg=$(cat "$1")
msg_code=$(echo "${current_msg}" | grep -iEo "$jira_code_pattern" | tail -n1)
msg_code=$(echo "${current_msg}" | grep -iEo "$JIRA_CODE_PATTERN" | tail -n1)
[ -z "$msg_code" ] || exit 0 # existing issue code in message

if case "$current_msg" in "fixup! "*) ;; *) false;; esac; then
Expand Down
Loading