Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Как запускать билд в Jenkins для последнего тега

github
git
jenkins
Теги: #<Tag:0x00007f7b61f96878> #<Tag:0x00007f7b61f96738> #<Tag:0x00007f7b61f942d0>

#1

Собственно сабж, столкнулся с казалось бы тривиальной задачей. Мне надо запускать билд, только при push tag и только если имя тега подпадает под регулярное выражение, пусть будет qa-[0-9]{6,8}. Код хранится на github, доступа к репозитарию нет, так что настроить хуки нет возможности.

У меня не получилось с ходу решить данную задачу. Jenkins просто не срабатывает при пуше нового тега.
В Refspec я использовал
+refs/tags/:refs/tags/

Branch Specifier (blank for ‘any’)
:qa_[0-9]{6,8}

Но к сожалению без результата.

Немного погуглив я так понял что он вообще такое не умеет. Сейчас пришлось вывернуться и создать два джоба, один проверяет наличие новых тегов и соответствие их регулярке, а затем вызывает второй параметризированный джоб, которому передает имя тега для билда.

Мб у кого то получилось решить задачу средствами самого Jenkins (git plugin)?

P.S.
Jenkins 2.7.2


(Stan) #2

Во-первых refspec должен быть +refs/tags/*:refs/remotes/origin/tags/*, во-вторых в бранче надо указывать бранч тэгов */tags/qa_[0-9]{6,8} (не уверен насчет регулярки, надо пробовать, попробуйте сначала все (*/tags/*) а потом уже написать регулярку, если все ок.


#3

какая разница, здесь мы лишь задаем соответствие между названиями локальных тегов и удаленных. Или я не правильно понимаю назначение refspec?

почему? Сейчас у меня в параметрической сборке передается просто имя тега, например, qa_12345678 и все отлично собирается

попробовал ваш вариант, отрабатывает, только если тег указывает на HEAD, тогда в логе я вижу

19:14:09 Started by an SCM change
19:14:09 [EnvInject] - Loading node environment variables.
19:14:09 Building in workspace /var/jenkins_home/workspace/p1
19:14:09  > git rev-parse --is-inside-work-tree # timeout=10
19:14:09 Fetching changes from the remote Git repository
19:14:09  > git config remote.origin.url ssh://git@193.243.xxx.xxx:2222/test/p1.git # timeout=10
19:14:09 Fetching upstream changes from ssh://git@193.243.xxx.xxx:2222/test/p1.git
19:14:09  > git --version # timeout=10
19:14:09 using GIT_SSH to set credentials 
19:14:09  > git -c core.askpass=true fetch --tags --progress ssh://git@193.243.xxx.xxx:2222/test/p1.git +refs/tags/*:refs/remotes/origin/tags/*
19:14:09 Seen branch in repository origin/api
19:14:09 Seen branch in repository origin/master
19:14:09 Seen branch in repository origin/tags/dev_1472738934
19:14:09 Seen branch in repository origin/tags/dev_1472841653
19:14:09 Seen branch in repository origin/tags/qa_1472735198
19:14:09 Seen branch in repository origin/tags/qa_1472737751
...
19:14:09 Checking out Revision 75c42ce06cbbff83e1640e4b7b28543ca6793167 (origin/tags/qa_1472930009)
19:14:09  > git config core.sparsecheckout # timeout=10
19:14:09  > git checkout -f 75c42ce06cbbff83e1640e4b7b28543ca6793167
19:14:09 First time build. Skipping changelog.
19:14:09 SSH: Connecting from host [9f68450a2695]

Если же я создаю тег, который указывает не на HEAD, то сборка просто игнорится, при этом в логах Git Polling Log новый тег появляется, но сборка не запускается, например,

# git rev-parse HEAD
75c42ce06cbbff83e1640e4b7b28543ca6793167

# git tag qa_$(date '+%s') 863c7607 && git push -u origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To ssh://git@193.243.xxx.xxx:2222/test/p1.git
 * [new tag]         qa_1472930540 -> qa_1472930540

То в логах полинга мы видим появление нового тега, но при этом сама сборка не активируется

Seen branch in repository origin/tags/qa_1472930009
Seen branch in repository origin/tags/qa_1472930540
Seen 41 remote branches
Done. Took 0.37 sec
No changes

Если же я добавляю новый комит и тегирую его

$ UT=$(date '+%s'); echo ${UT} > 1 && git add . && git commit -m "${UT}" && git push -u origin api
[api 8f80708] 1472931220
 1 file changed, 1 insertion(+), 1 deletion(-)
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 268 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To ssh://git@193.243.xxx.xxx:2222/test/p1.git
   75c42ce..8f80708  api -> api
Branch api set up to track remote branch api from origin.

$ git tag qa_$(date '+%s') 8f80708  && git push -u origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To ssh://git@193.243.xxx.xxx:2222/test/p1.git
 * [new tag]         qa_1472931234 -> qa_1472931234

То все отрабатывает.

Seen branch in repository origin/tags/qa_1472930009
Seen branch in repository origin/tags/qa_1472930540
Seen branch in repository origin/tags/qa_1472931137
Seen branch in repository origin/tags/qa_1472931234
Seen 43 remote branches
 > git log --full-history --no-abbrev --format=raw -M -m 75c42ce06cbbff83e1640e4b7b28543ca6793167..8f807082e7c7dc3c33ea46dc6146b2bc5d3be3a8 # timeout=10
Done. Took 0.68 sec
Changes found

Но мне надо иметь возможность собирать любой коммит, а не только head.

Мб такое поведение как то связано с тем, что после того, как Jenkins делает обновление кода в WORKSPACE, то мы получаем т.н. detached HEAD ?


(Stan) #4

теперь полностью понял, что вы имеете ввиду. Так, а если вы тэгите старый коммит или вторично существующий, логично что он уже собирался хотя бы раз?


#5

Нет, не обязательно. В том и смысл данного джоба, чтобы запускаться только при появлении нового тега, а не коммита. Т.е. грубо говоря, разработчик делает что то типа

git commit 1 -> hash 1
git commit 2 -> hash 2
git commit 3 -> hash 3
git tag qa_1 hash 2
git push

в таком случае, хед будет смотреть на hash3, а собрать мне надо hash 2


#6

Заметил такую особенность, что данная схема работает только в прямом порядке. Например если у нас есть такая последовательность коммитов/тегов

550313e  -> 22ce31f -> e31e663 -> e4c4bf6 (head)
  tag1       tag2        tag3       tag4

То будет выполнено 4 билда как и должно быть, но если у нас такая последовательность

5c22d29 -> 653af25 -> aba3b93 -> ced9cac (new head)
  tag6       tag7       tag5       tag8 

То в таком случае билд будет запущен только для tag5 и tag8, а вот tag6/7 будут проигнорированы.