├── .gitlab-ci.yml ├── CHANGELOG.md ├── Dockerfile ├── README.md └── merge-request.sh /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - openMr 3 | - otherStages 4 | 5 | Open Merge Request: 6 | image: tmaier/gitlab-auto-merge-request 7 | before_script: [] # We do not need any setup work, let's remove the global one (if any) 8 | variables: 9 | GIT_STRATEGY: none # We do not need a clone of the GIT repository to create a Merge Request 10 | stage: openMr 11 | only: 12 | - /^feature\/*/ # We have a very strict naming convention 13 | script: 14 | - merge-request.sh # The name of the script 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## 1.0.0 - 2017-09-10 10 | ### Added 11 | - Add Dockerfile 12 | - Add script from 13 | - Add check if `$GITLAB_PRIVATE_TOKEN` is set 14 | - Fail entire script on errors 15 | 16 | ### Changed 17 | - Rename `$PRIVATE_TOKEN` to `$GITLAB_PRIVATE_TOKEN` 18 | - Replace Python with [jq](https://stedolan.github.io/jq) to handle JSON 19 | - Change `.gitlab-ci.yml` 20 | - Use Docker Image 21 | - Skip cloning git repository 22 | 23 | [Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/master...develop 24 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.6 2 | MAINTAINER Tobias L. Maier 3 | 4 | RUN apk add --no-cache \ 5 | bash \ 6 | curl \ 7 | grep \ 8 | jq 9 | 10 | COPY merge-request.sh /usr/bin/ 11 | 12 | CMD ["merge-request.sh"] 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Open GitLab Merge Requests automatically 2 | 3 | [![Docker Automated buil](https://img.shields.io/docker/automated/tmaier/gitlab-auto-merge-request.svg)](https://hub.docker.com/r/tmaier/gitlab-auto-merge-request/) 4 | [![Docker Pulls](https://img.shields.io/docker/pulls/tmaier/gitlab-auto-merge-request.svg)](https://hub.docker.com/r/tmaier/gitlab-auto-merge-request/) 5 | [![Gitlab Project](https://img.shields.io/badge/GitLab-Project-554488.svg)](https://gitlab.com/tmaier/gitlab-auto-merge-request) 6 | 7 | This script is meant to be used in GitLab CI to automatically open Merge Requests for feature branches, if there is none yet. 8 | 9 | The script is provided as dedicated docker image to improve maintainability in the future. 10 | 11 | It is based on the script and idea of [Riccardo Padovani](https://rpadovani.com), which he introduced with his blog post [How to automatically create new MR on Gitlab with Gitlab CI](https://rpadovani.com/open-mr-gitlab-ci). 12 | Thanks for providing this. 13 | 14 | ## Instructions 15 | 16 | ### 1) `GITLAB_PRIVATE_TOKEN` 17 | Set a secret variable in your GitLab project with your private token. 18 | Name it `GITLAB_PRIVATE_TOKEN`. 19 | This is necessary to raise the Merge Request on your behalf. 20 | 21 | ### 2) `.gitlab-ci.yml` 22 | 23 | Add the following to your `.gitlab-ci.yml` file: 24 | 25 | ```yaml 26 | stages: 27 | - openMr 28 | - otherStages 29 | 30 | Open Merge Request: 31 | image: tmaier/gitlab-auto-merge-request:1 32 | before_script: [] # We do not need any setup work, let's remove the global one (if any) 33 | variables: 34 | GIT_STRATEGY: none # We do not need a clone of the GIT repository to create a Merge Request 35 | stage: openMr 36 | only: 37 | - /^feature\/*/ # We have a very strict naming convention 38 | script: 39 | - merge-request.sh # The name of the script 40 | ``` 41 | 42 | You can see this in action at [`.gitlab-ci.yml` of this project](.gitlab-ci.yml). 43 | 44 | ## Docker images 45 | 46 | The images are hosted on [Docker Hub](https://hub.docker.com/r/tmaier/gitlab-auto-merge-request). 47 | 48 | Two tags are noteworthy: 49 | * `latest`: Latest release on `master` branch of this project 50 | * `1`: Latest stable release of `1.x` version (see note on Semantic Versioning below) 51 | 52 | ## This project is managed on GitLab 53 | 54 | The [GitHub project][] is only a mirror of the [GitLab project][]. 55 | 56 | [GitHub project]: https://github.com/tmaier/gitlab-auto-merge-request 57 | [GitLab project]: https://gitlab.com/tmaier/gitlab-auto-merge-request 58 | 59 | Please open Issues and Merge Requests at the [GitLab project][]. 60 | 61 | ## Versioning 62 | 63 | This project follows [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 64 | Following are defined as APIs according to the spec: 65 | * How to call this script from `.gitlab-ci.yml` 66 | * Required Environment Variables 67 | 68 | Following are not considered as API according to the spec: 69 | * `Dockerfile` and base image used 70 | 71 | ## Authors 72 | 73 | * Docker part: [Tobias L. Maier](http://tobiasmaier.info) 74 | * Script and idea: [Riccardo Padovani](https://rpadovani.com) 75 | -------------------------------------------------------------------------------- /merge-request.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ -z "$GITLAB_PRIVATE_TOKEN" ]; then 5 | echo "GITLAB_PRIVATE_TOKEN not set" 6 | echo "Please set the GitLab Private Token as GITLAB_PRIVATE_TOKEN" 7 | exit 1 8 | fi 9 | 10 | # Extract the host where the server is running, and add the URL to the APIs 11 | [[ $CI_PROJECT_URL =~ ^https?://[^/]+ ]] && HOST="${BASH_REMATCH[0]}/api/v4/projects/" 12 | 13 | # Look which is the default branch 14 | TARGET_BRANCH=`curl --silent "${HOST}${CI_PROJECT_ID}" --header "PRIVATE-TOKEN:${GITLAB_PRIVATE_TOKEN}" | jq --raw-output '.default_branch'`; 15 | 16 | # The description of our new MR, we want to remove the branch after the MR has 17 | # been closed 18 | BODY="{ 19 | \"id\": ${CI_PROJECT_ID}, 20 | \"source_branch\": \"${CI_COMMIT_REF_NAME}\", 21 | \"target_branch\": \"${TARGET_BRANCH}\", 22 | \"remove_source_branch\": true, 23 | \"title\": \"WIP: ${CI_COMMIT_REF_NAME}\", 24 | \"assignee_id\":\"${GITLAB_USER_ID}\" 25 | }"; 26 | 27 | # Require a list of all the merge request and take a look if there is already 28 | # one with the same source branch 29 | LISTMR=`curl --silent "${HOST}${CI_PROJECT_ID}/merge_requests?state=opened" --header "PRIVATE-TOKEN:${GITLAB_PRIVATE_TOKEN}"`; 30 | COUNTBRANCHES=`echo ${LISTMR} | grep -o "\"source_branch\":\"${CI_COMMIT_REF_NAME}\"" | wc -l`; 31 | 32 | # No MR found, let's create a new one 33 | if [ ${COUNTBRANCHES} -eq "0" ]; then 34 | curl -X POST "${HOST}${CI_PROJECT_ID}/merge_requests" \ 35 | --header "PRIVATE-TOKEN:${GITLAB_PRIVATE_TOKEN}" \ 36 | --header "Content-Type: application/json" \ 37 | --data "${BODY}"; 38 | 39 | echo "Opened a new merge request: WIP: ${CI_COMMIT_REF_NAME} and assigned to you"; 40 | exit; 41 | fi 42 | 43 | echo "No new merge request opened"; 44 | --------------------------------------------------------------------------------