Чему вы научитесь
- Что такое битбакетные пайплайны, как и где их можно использовать
- Каковы преимущества автоматизации запросов на вытягивание в вашем проекте?
- Необходимые условия для работы автоматики
- Автоматизируйте запрос на вытягивание с помощью конвейеров битбакета
- Автоматизируйте запрос на вытягивание с помощью конвейеров битбакета и javascript.
Что такое битбакетные пайплайны, как и где их можно использовать
Bitbucket Pipelines — это интегрированная служба CI/CD, встроенная в Bitbucket. Он позволяет автоматически создавать, тестировать и даже развертывать код на основе файла конфигурации в вашем репозитории. По сути, мы создаем для вас контейнеры в облаке. Внутри этих контейнеров вы можете запускать команды (как на локальной машине), но со всеми преимуществами свежей системы, настроенной под ваши нужды (Узнайте, как начать).
Эти команды включают в себя установку пакетов, выполнение запросов API с помощью curl, сохранение переменных, запуск задач javascript и многое другое. Теперь, когда у нас есть преимущества хранения переменных и установки пакетов, выполнения запросов API и выполнения задач javascript, мы можем создавать запросы на вытягивание из одной ветки в другую в вашем репозитории Bitbucket.
Конвейеры Bitbucket можно использовать для автоматизации нескольких операций, просто выполняя серию команд, как если бы вы запускали их со своего терминала. Эти операции включают, помимо прочего, создание запросов на вытягивание, объединение запросов на вытягивание, развертывание кода на удаленном сервере, модульные тесты, e2e-тесты, изменение версий в файлах package.json, чтение и запись файлов и многое другое. В clickpesa мы используем конвейеры битбакетов для выполнения всех этих операций.
Каковы преимущества автоматизации запросов на вытягивание в вашем проекте?
- Улучшить процесс разработки (участникам не нужно вручную создавать PR для другой ветки)
- Сокращает количество человеческих ошибок, таких как создание PR для неправильной ветки.
- Полезно для команды с большим количеством участников/разработчиков
- Помогает в форматировании PR-описаний. Это помогает рецензентам понять, какие изменения в PR перед слиянием с другой веткой.
Предпосылки
Аутентификация вашего рабочего пространства для авторизации выполнения операций от вашего имени.
я. Создайте потребителя OAuth в своей рабочей области. Перейдите в свою рабочую область bitbucket → настройки → Потребители OAuth → Добавить потребителя.
II. Заполните необходимую информацию, особенно имя, и дайте вашему новому потребителю разрешения для различных операций, но в нашем случае мы дадим разрешение на чтение и запись запросов на вытягивание. Обязательно установите флажок Это частный потребитель и URL-адрес обратного вызова (вы можете добавить любой URL-адрес).
III. После сохранения потребителя щелкните его, чтобы просмотреть ключ и секрет.
Откройте другую вкладку и посетите репозиторий, где запрос на включение будет автоматизирован. Если в вашем репозитории нет конвейеров bitbucket, пропустите эту часть и просмотрите шаг v. Для этого действия необходим доступ администратора. После посещения репозитория перейдите в Настройки репозитория → Переменные репозитория (здесь мы должны иметь возможность добавлять переменные).
IV. Создайте переменную с любым именем, скажем, BB_AUTH_STRING, и значения должны быть добавлены как ключ: значение, например VzW7ubArG8T3huEDXs:eRNqGCycMVPvfzsGhEyd7xP33tYLd2jZ, эта переменная должна быть защищена. Теперь мы можем использовать это значение в качестве переменной в конвейере для аутентификации пользователей.
v. (если вы не настроили конвейеры в своем проекте). В репозитории на боковой панели перейдите к конвейерам → выберите начальный конвейер → зафиксируйте конвейер в своем репозитории. Поздравляем, вы создали свои первые конвейеры битбакетов, после этого вернитесь к шагу c.
Шаги
Примечание: файлы .yml имеют набор правил в своих сценариях, таких как правила отступов
Создание запроса на извлечение с использованием только конвейеров
я. У нас уже есть созданные пайплайны, удаляем все элементы и начнем заново, давайте запустим скрипт hello world с помощью пайплайна, пайплайны битбакета содержат кучу пайплайнов по выбору пользователя, пока давайте придерживаться веток, пайплайн будет работать только в случае изменений выталкиваются на ветку
pipelines:
branches:
master:
- step:
name: first pipelines
script:
- echo " - ✨ Hello World!!"
Выход
II. Хватит этих простых вещей, давайте перейдем к основной теме. Сначала нам нужно создать новую ветку, скажем, develop, в которой мы будем автоматизировать запрос на извлечение из ветки develop в ветку master.
- В конвейере измените имя ветки с master на development. Затем установите curl и jq, curl используется для запросов API в терминале, а jq используется для форматирования ответов.
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
III. Используя переменную аутентификации, которую мы сохранили ранее, создайте запрос curl для получения токена авторизации. Сохраните его в переменной битбакета, скажем, BB_TOKEN. Используйте jq для извлечения токена из ответа.
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
- >
export BB_TOKEN=$(curl -s -S -f -X POST -u "${BB_AUTH_STRING}" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=client_credentials -d scopes="repository" | jq --raw-output '.access_token')
- echo $BB_TOKEN
- Давайте создадим наш первый запрос на вытягивание с пайплайнами.
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
- >
export BB_TOKEN=$(curl -s -S -f -X POST -u "${BB_AUTH_STRING}" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=client_credentials -d scopes="repository" | jq --raw-output '.access_token')
- echo $BB_TOKEN
- >
curl https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/pullrequests \
-s -S -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${BB_TOKEN}" \
-d '{
"title": "Automated Pull request",
"description": "",
"source": {
"branch": {
"name": "develop"
}
},
"destination": {
"branch": {
"name": "master"
}
},
"close_source_branch": false,
"reviewers": '[]'
}’
- Поздравляем, вы создали свой первый PR с пайплайнами
IV. Мы создали самый простой запрос на пулл-реквест, в сложной части нам нужно динамически добавить рецензентов по умолчанию и описания (из коммитов).
- Сначала выберите рецензентов проекта по умолчанию, запустив другой запрос curl непосредственно перед созданием запроса на вытягивание. Отформатируйте ответ с помощью jq, чтобы он содержал только массив uuid рецензентов, участник не может быть рецензентом.
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
- >
export BB_TOKEN=$(curl -s -S -f -X POST -u "${BB_AUTH_STRING}" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=client_credentials -d scopes="repository" | jq --raw-output '.access_token')
- echo $BB_TOKEN
- >
export DEFAULT_REVIEWERS=$(curl https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/default-reviewers \
-s -S -f -X GET \
-H "Authorization: Bearer ${BB_TOKEN}" | jq '.values' | jq 'map({uuid})' )
- echo $DEFAULT_REVIEWERS
- Передайте созданный массив рецензентов по умолчанию в полезной нагрузке запроса на вытягивание.
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
- >
export BB_TOKEN=$(curl -s -S -f -X POST -u "${BB_AUTH_STRING}" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=client_credentials -d scopes="repository" | jq --raw-output '.access_token')
- echo $BB_TOKEN
- >
export DEFAULT_REVIEWERS=$(curl https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/default-reviewers \
-s -S -f -X GET \
-H "Authorization: Bearer ${BB_TOKEN}" | jq '.values' | jq 'map({uuid})' )
- echo $DEFAULT_REVIEWERS
- >
curl https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/pullrequests \
-s -S -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${BB_TOKEN}" \
-d '{
"title": "Automated Pull request",
"description": "",
"source": {
"branch": {
"name": "develop"
}
},
"destination": {
"branch": {
"name": "master"
}
},
"close_source_branch": false,
"reviewers": '"${DEFAULT_REVIEWERS}"'
}’
v. Добавление коммитов в описания запроса на вытягивание, сначала давайте выберем коммиты, коммиты можно получить, сравнивая изменения между двумя ветвями, в нашем случае мы сравниваем разработку ветки и master, а различия заключаются в коммитах, которые мы отправим в виде описаний запроса на вытягивание. В этой части у нас могут быть коммиты из других веток, которые будут включать сообщения о коммитах, начинающиеся с merged in {название ветки}, которые нам не нужно показывать рецензентам, коммиты можно отфильтровать, чтобы исключить нежелательные коммиты, создать пустую строку переменная и зациклить возвращенные коммиты, в каждом цикле добавляйте коммит, если он помещается в пустую строку.
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
- >
export BB_TOKEN=$(curl -s -S -f -X POST -u "${BB_AUTH_STRING}" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=client_credentials -d scopes="repository" | jq --raw-output '.access_token')
- >
export COMMITS=$(curl -H "Authorization: Bearer ${BB_TOKEN}" -d "include=develop" -d "exclude=master" "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/commits")
- echo $COMMITS
- export COMMIT_MESSAGES=""
- export value=""
- >
for i in $(jq '.values | keys | .[]' <<< "$COMMITS"); do
value=$(jq -r ".values[$i]" <<< ${COMMITS})
message=$(jq -r '.message' <<< "$value")
- if [[ "$message" != *"Merge"* ]]; then
COMMIT_MESSAGES="$COMMIT_MESSAGES> "$message"\n\n"
- fi
done
- echo $COMMIT_MESSAGES
- Добавьте полученную строку в часть описания полезной нагрузки запроса на вытягивание и зафиксируйте, название запроса на вытягивание также может быть изменено динамически.
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
- >
export BB_TOKEN=$(curl -s -S -f -X POST -u "${BB_AUTH_STRING}" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=client_credentials -d scopes="repository" | jq --raw-output '.access_token')
- >
export DEFAULT_REVIEWERS=$(curl https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/default-reviewers \
-s -S -f -X GET \
-H "Authorization: Bearer ${BB_TOKEN}" | jq '.values' | jq 'map({uuid})' )
- echo $DEFAULT_REVIEWERS
- >
export COMMITS=$(curl -H "Authorization: Bearer ${BB_TOKEN}" -d "include=develop" -d "exclude=master" "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/commits")
- echo $COMMITS
- export COMMIT_MESSAGES=""
- export value=""
- >
for i in $(jq '.values | keys | .[]' <<< "$COMMITS"); do
value=$(jq -r ".values[$i]" <<< ${COMMITS})
message=$(jq -r '.message' <<< "$value")
- if [[ "$message" != *"Merge"* ]]; then
COMMIT_MESSAGES="$COMMIT_MESSAGES> "$message"\n\n"
- fi
done
- echo $COMMIT_MESSAGES
- >
curl https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/pullrequests \
-s -S -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ${BB_TOKEN}" \
-d '{
"title": "Automated Pull request",
"description":"'"${COMMIT_MESSAGES}"'",
"source": {
"branch": {
"name": "develop"
}
},
"destination": {
"branch": {
"name": "master"
}
},
"close_source_branch": false,
"reviewers": '"${DEFAULT_REVIEWERS}"'
}’
- Поэкспериментировав с этим, в определенный момент создание запроса на вытягивание вернет ошибку 400 — Bad request и не даст никаких дополнительных описаний ошибок. Не волнуйтесь, для этого есть решение.
Альтернативное решение (с использованием javascript)
- Запросы на вытягивание можно создавать с помощью javascript, используя fetch api или axios.
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${authorization token}`,
};
const postData = {
title: `title`,
description: `description`,
source: {
branch: {
name: `develop`,
},
},
destination: {
branch: {
name: "master",
},
},
close_source_branch: false,
reviewers: [],
};
const url = `https://api.bitbucket.org/2.0/repositories/${repo_owner}/${repo_name}/pullrequests`
const { data } = axios.post(url, postData, { headers });
console.log(data)
II. Но эту функцию нельзя вызвать прямо в пайплайне, тут в дело вступает Gulp Js. Для этого нужно установить несколько пакетов, (для этой операции требуется nodejs)
npm install gulp axios –save-dev
- Создайте файл с именем gulpfile.js.
- С помощью gulp мы можем создать задачу в javascript и вызвать эту задачу в конвейере, который вызовет функцию, определенную этой задачей в javascript.
- Создайте задачу createpr в gulpfile. Зафиксируйте свои изменения и нажмите. Проверьте конвейеры битбакета, и запросы на вытягивание будут созданы.
const gulp = require("gulp"); const axios = require("axios").default; gulp.task("createpr", async () => { const headers = { "Content-Type": "application/json", // make sure to pass the token Authorization: `Bearer ${authorization_token}`, }; const postData = { title: “title”, description: “”, source: { branch: { name: “develop”, }, }, destination: { branch: { name: "master", }, }, close_source_branch: false, reviewers: [], }; const url = `https://api.bitbucket.org/2.0/repositories/${repo_owner}/${repo_name}/pullrequests` const { data } = axios.post(url, postData, { headers }); console.log(data) }
# nodejs image is required image: node:14.16.1 pipelines: branches: develop: - step: name: automate pull request script: - apt-get update - apt-get -y install curl jq # install gulp globally - npm i -g gulp # this will list all defined tasks in the gulpfile we’ve created - gulp –tasks - gulp createpr # this will call the function we defined to create pull request.
III. Поскольку нам нужны переменные из конвейера, такие как токен авторизации, имя ветки, имя репо, коммиты и т. д., задача будет получать переменные из конвейера, используя process.argv[variable number]
, номер переменной — это позиция переменной, определенной в конвейере, например, наша задача — createpr , назовем его gulp createpr --t $BB_TOKEN --b "develop" --o $BITBUCKET_REPO_OWNER --s $BITBUCKET_REPO_SLUG --d "$COMMIT_MESSAGES"
, где BB_TOKEN — токен авторизации, BITBUCKET_REPO_OWNER и BITBUCKET_REPO_SLUG уже доступны в конвейере и не нуждаются в определении. При подсчете от gulp BB_TOKEN является четвертым элементом, поэтому мы можем использовать его как process.argv[4]
, а для исходной ветки (разработки) можно вызвать как process.argv[6]
то же самое относится и к другим переменным.
# nodejs image is required
image: node:14.16.1
pipelines:
branches:
develop:
- step:
name: automate pull request
script:
- apt-get update
- apt-get -y install curl jq
- >
export BB_TOKEN=$(curl -s -S -f -X POST -u "${BB_AUTH_STRING}" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=client_credentials -d scopes="repository" | jq --raw-output '.access_token')
- >
export DEFAULT_REVIEWERS=$(curl https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/default-reviewers \
-s -S -f -X GET \
-H "Authorization: Bearer ${BB_TOKEN}" | jq '.values' | jq 'map({uuid})' )
- echo $DEFAULT_REVIEWERS
- >
export COMMITS=$(curl -H "Authorization: Bearer ${BB_TOKEN}" -d "include=develop" -d "exclude=master" "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/commits")
- echo $COMMITS
- export COMMIT_MESSAGES=""
- export value=""
- >
for i in $(jq '.values | keys | .[]' <<< "$COMMITS"); do
value=$(jq -r ".values[$i]" <<< ${COMMITS})
message=$(jq -r '.message' <<< "$value")
- if [[ "$message" != *"Merge"* ]]; then
COMMIT_MESSAGES="$COMMIT_MESSAGES> "$message"\n\n"
- fi
done
- echo $COMMIT_MESSAGES
- npm i -g gulp
- gulp –tasks
- gulp createpr --t $BB_TOKEN --b "develop" --o $BITBUCKET_REPO_OWNER --s $BITBUCKET_REPO_SLUG --d "$COMMIT_MESSAGES" –r $DEFAULT_REVIEWERS
const gulp = require("gulp");
const axios = require("axios").default;
gulp.task("createpr", async () => {
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${process.argv[4]}`,
};
const postData = {
title: `${process.argv[6]}`,
description: `${process.argv[12]}`,
source: {
branch: {
name: `${process.argv[6]}`,
},
},
destination: {
branch: {
name: "master",
},
},
close_source_branch: true,
reviewers: process.argv[14] ,
};
const url = `https://api.bitbucket.org/2.0/repositories/${process.argv[8]}/${process.argv[10]}/pullrequests`;
const { data } = axios.post(url, postData, { headers });
console.log(data)
}
IV. Зафиксируйте свои изменения и нажмите. Проверьте конвейеры битбакета, и запросы на вытягивание будут созданы.