Страницы

Поиск по вопросам

Показаны сообщения с ярлыком gitlab. Показать все сообщения
Показаны сообщения с ярлыком gitlab. Показать все сообщения

четверг, 5 марта 2020 г.

Как git работает со ссылками

#git #gitlab


Здравствуйте.
Мне нужно завести проект в gitlab. В проекте есть symlink'и как на директории так
и на файлы. Мой вопрос такой, как git работает со ссылками? Имеет ли значение идет
ссылка на файл или директорию? Если я хочу добавить их в .gitignore, мне просто добавлять
их как конкретные файлы?
    


Ответы

Ответ 1



git сохраняет symlink так же как файл в blob. При checkout он создаст его как symlink и не важно есть ли оригинальный файл/директория. Вы можете добавить их в .gitignore как простые файлы по имени.

среда, 12 февраля 2020 г.

Jenkins запуск build проекта после push

#gitlab #build #jenkins


Доброго времени суток. Первый раз столкнулся с задачами CI. Проблема - не получается
адекватно настроить Jenkins. Что требуется: после push проекта на GitLab (именно после
push, это важно), Jenkins должен попытаться собрать проект.

Шаги предпринятые для решения этой проблемы:


Jenkins сервер поднят и настроен, и работает по адресу jenkinsaddres:port
На Jenkins сервере есть GitLab connection опция которая настроена на gitlabhost,
GitLab API token задан и test connection возвращает радостное success.
Добавлен проект, Source Code Management, Repository URL, Credentials, Branch Specifier
настроены.
В проекте опции Build when a change is pushed to GitLab. GitLab CI Service URL: jenkinsaddres:port/project/test
активна, GitLab Triggers: Push events опция так же активна.
GitLabProject -> Settings -> Web hook -> jenkinsaddres:port/project/test, и опция
Push Events тоже активна.


Проект build'ится по расписанию, или вручную но никак не хочет собираться даже при
тестовой отправке hook'а с GitLab. POST сообщение доходит следующего вида source: gitlabhost;
destination: jenkinsaddres; Protocol: HTTP; info: POST /project/test HTTP/1.1 (application/json).
Ответ: адреса верные поэтому не буду их показывать, поле info: HTTP/1.1 404 Not Found
(text/html).

Если на Jenkins выключить все secure опции, и посылать hook на jenkinsaddres:port/job/test(сюда
он стягивает проекты) то тогда объект все-таки находится: Found. Но оказывается что
изменений Jenkins не видит (Not Modified), думаю поэтому проект и не ребилдится.
    


Ответы

Ответ 1



Борюсь с подобной же проблемой. Статья https://github.com/jenkinsci/gitlab-plugin/issues/298 дала следующую подсказку - тестируют с POST а не GET, что возвращает 403 так как "anonymous is missing the Job/Build permission". Два решения по починке https://github.com/jenkinsci/gitlab-plugin/issues/375 Если не заработает после правки - стоит проверить имя проекта. Если что есть URL encoded - это проблемма Так Unit Tests не работает, а UnitTests работает.

Ответ 2



Можно использовать триггер с токеном, он позволяет запускать сборку даже анонимному пользователю. Например, в моем дженкинсе аноним имеет разрешение только на просмотр (Read) задач и сборок. Но хуки работают из Гитлаба, curl'ом и просто через браузер. В конфигурации задачи example_jenkins_job: Хук в Гитлабе: http://jenkinsaddress:port/job/example_jenkins_job/build?token=secret_token Или, если задача параметризованная: http://jenkinsaddress:port/job/example_jenkins_job /buildWithParameters?token=secret_token В этом случае будет запущена сборка с дефолтными значениями параметров. Вы можете передавать собственные значения параметров следующим образом: http://jenkinsaddress:port/job/example_jenkins_job /buildWithParameters?token=secret_token¶m1=value1¶m2=value2 Можно добавить причину сборки: &cause=Cause+Text Она сохранится в информации о сборке: И в логе сборки, первой строкой: Started by remote host 127.0.0.1 with note: Cause Text

суббота, 11 января 2020 г.

Gitlab pages для своего Gitlab

#github #gitlab


Gitlab pages позволяет публиковать index.html туда. 

Есть свой развернутый GitLab последней версии. что мне нужно делать, чтобы я смог
использовать свой основной DNS и опубликовал также сайт? 
    


Ответы

Ответ 1



Нужно установить и запустить GitLab Pages daemon — это их собственный вебсервер. Он может быть установлен как на одном хосте с гитлабом, так и на отдельном. Поставляется он в пакете Omnibus или отдельно. Подробные инструкции есть в GitLab Pages configuration. Также можно установить и сконфигурировать с помощью роли Ansible debops.ansible-gitlab.

среда, 25 декабря 2019 г.

автоматическое тестирование проектов на gitlab

#java #github #gitlab #test_automation


начинающий юзер гитлаба, просьба не пинать ногами, меня интересует тестирование java-проектов
на автомате, то есть написал тесты закинул в проект на гитлабе и они работают на автомате

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


Ответы

Ответ 1



Есть три независимых друг от друга задачи: Написать сами тесты и реализовать возможность их запуска из командной строки. Можно просто команду, можно в .sh обернуть. Главное: тесты должны действительно фейлиться при запуске, то есть: Если тесты успешны, запускатор тестов возвращает 0. Если тесты неуспешны, запускатор возвращает что угодно другое. Установить и настроить GitLab CI Runner на машине с нужной вам ОС. Если вы пользуетесь gitlab.com, можете воспользоваться раннерами, предоставленными GitLab. Потом настроить ваш репозиторий на этот раннер. Добавить в корневую папку проекта файл .gitlab-ci.yml. Это файл в разметке Yaml, он описывает конвейер (pipeline) сборки проекта. Если GitLab видит этот файл в коммите, он пытается запустить сборку. Содержимое .gitlab-ci.yml примерно такое # если используем Docker-runner # то, например, такой образ Java можно использовать image: openjdk:7 # у нас будет только один этап сборки — тест stages: - test # и в нём только одна задача test_job: stage: test script: # предположим, что тесты мы запускаем с помощью Maven - mvn test

Ответ 2



Вам нужно прочитать документацию по настройке файла .gitlab-ci.yml Он запускает ранеры для выполнения задач при комите или мерже в зависимости он его настроек. https://docs.gitlab.com/ce/ci/yaml/ Вам также нужно будет настроить сам ранер (в начале можно на той-же машине что и gitlab ) https://docs.gitlab.com/runner/

вторник, 24 декабря 2019 г.

Cкачать (fetch) с GitLab содержимое запроса на слияние (merge request)

#git #gitlab #git_remote


Сервер Gitlab, организую работу через запросы на слияние (merge request, pull request).

При создании запроса хотелось бы иметь URL, из которого Jenkins смог бы выкачивать
последний коммит ветки, которая предлагается к слиянию.

Есть ли возможность в Gitlab получить такой URL?


какой-нибудь alias к ветке, предлагаемой к слиянию?
автоматически создаваемый предварительный коммит? (т.е. что бы получилось, если прямо
сейчас нажать кнопку Merge Request?


Знаю, что-то подобное возможно в Gitlab CI и GitHub CI, на этих коммитах даже тесты
прогоняются. Поэтому возможен и третий вариант:


Работать с Jenkins как с Gitlab CI?


Перейти полностью на Gitlab CI - не вариант, это будут неоправданные затраты.
    


Ответы

Ответ 1



автоматически создаваемый предварительный коммит? (т.е. что бы получилось, если прямо сейчас нажать кнопку Merge Request? Фича пока не реализована, можно проголосовать. какой-нибудь alias к ветке, предлагаемой к слиянию? Реализовано. На каждый merge request гитлаб создаёт внутри себя отдельный указатель в refs/merge-requests. Нужно просто настроить свой репозиторий, чтобы при git fetch забирать эти указатели. Открываем .git/config, находим в нём блок, соответствующий репозиторию. [remote "origin"] url = https://gitlab.com/gitlab-org/gitlab-ce.git fetch = +refs/heads/*:refs/remotes/origin/* Добавляем в него строку +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*. Теперь должно выглядеть так: [remote "origin"] url = https://gitlab.com/gitlab-org/gitlab-ce.git fetch = +refs/heads/*:refs/remotes/origin/* fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/* Обновляем данные: $ git fetch origin From https://gitlab.com/gitlab-org/gitlab-ce.git * [new ref] refs/merge-requests/1/head -> origin/merge-requests/1 * [new ref] refs/merge-requests/2/head -> origin/merge-requests/2 Теперь можно создать новую локальную ветку, отслеживающую соответствующий merge request. $ git checkout merge-requests/1 Branch merge-requests/1 set up to track remote branch merge-requests/1 from origin. Switched to a new branch 'merge-requests/1' Примеры взяты из документации GitLab. Там же есть более подробные инструкции.

Как правильно задать редактор?

#ubuntu #git #github #gitlab


Вот я работаю с терминалом и когда хочу поверить изменения в гит

git diff 


то он все показывает в терминале

я так понял, что с помощью команды 

git config --global core.editor "kate"


можно установить редактор который будет показывать внесенные изменения

kate - это название редактора

После того как я выполнил эту команду я проверил файл .gitconfig и там это отобразилось

[user]
name = aleksey
email = aleksey@gmail.com
[core]
autocrlf = input
excludesfile = /home/aleksey/.gitexcludes
editor = kate


В последней строчке.

Но все равно когда я в терминале набираю git diff все открывается в терминале...

Подскажите как это исправить?
    


Ответы

Ответ 1



Нет, не совсем правильно Редактор git — это тот редактор, которым вы пишете сообщения коммитов. То есть сейчас если вы запустите git commit (--amend, если хотите только проверить), то у вас откроется kate для написания коммита. Если вы хотите посмотреть изменения в каком-то графическом редакторе, то можете перенаправить системными средствами stdout в файл и открыть его каким-либо редактором *. Например: git diff > out.txt && kate out.txt * Тут меня должны поправить более компетентные люди, что правильнее смотреть diff-ы в difftool и соответствующих инструментах, отображающие изменения более наглядно, но я не слишком в этом компетентен. Можно попробовать запустить git difftool --tool-help, который отобразит все возможные (и доступные) для просмотра изменений редакторы (их можно доустановить). Вот пример запуска утилиты git difftool --tool=vimdiff Конечно же эти редакторы можно установить глобально или на проект (чтобы не писать постоянно --tool)

понедельник, 16 декабря 2019 г.

Может ли Gitlab CI собирать с GitHub?

#github #gitlab #непрерывная_интеграция #gitlab_ci


Собственно вопрос главный в заголовке.
Интересует возможность собирать в своем Gitlab CI проекты опенсорсные с github. 
И если есть такая возможность, то подскажите как это реализуется.  

Вариант перенести проект в Gitlab не подходит.                      
    


Ответы

Ответ 1



GitLab CI позволяет собирать только те проекты, которые находятся в самом GitLab, поскольку при работе он использует информацию о репозиториях, хранящуюся в самом GitLab. Единственный вариант решения: зеркалировать репозиторий с Github на репозиторий в GitLab, и уже для последнего настроить билды.

Ответ 2



Нужно добавить в gitlab-ci.yml: checkout_github: script: git clone https://github.com/<какой-то репзиторий>.git Ну а дальше соответственно должны идти шаги сборки

понедельник, 9 декабря 2019 г.

Как оптимизировать деплой через docker-compose?

#php #docker #gitlab #docker_compose #gitlab_ci


Мы реализовали деплой через GitLab CI и docker-compose. В процессе деплоя на удалённый
сервер копируется файл docker-compose.yml и файлы Dockerfile и пр. для создания "вспомогательных"
контейнеров типа nginx и mysql

Всё работает как нужно. Беспокоят 2 момента: даунтайм и "мусорные" образы docker
(те, что с  в колонке TAG в docker images)

Вот кусок файла .gitlab-ci.yml, ответственный собственно на деплой на удалённый сервер:

.template-secure-copy: &secure-copy
    stage: deploy
    image: covex/alpine-git:1.0
    before_script:
      - eval $(ssh-agent -s)
      - ssh-add <(echo "$SSH_PRIVATE_KEY")
    script:
      - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ;
          rm -rf '"$DEPLOY_DIRECTORY"'_tmp ;
          mkdir -p '"$DEPLOY_DIRECTORY"'_tmp'
      - scp -P 22 -r build/* ''"$DEPLOY_USER"'@'"$DEPLOY_HOST"':'"$DEPLOY_DIRECTORY"'_tmp'
# */ <-- в оригинале строка не закоментирована =)
      - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ;
          cd '"$DEPLOY_DIRECTORY"'_tmp ;
          docker login -u gitlab-ci-token -p '"$CI_JOB_TOKEN"' '"$CI_REGISTRY"' ;
          docker-compose pull ;
          if [ -d '"$DEPLOY_DIRECTORY"' ]; then cd '"$DEPLOY_DIRECTORY"' && docker-compose
down --rmi local && rm -rf '"$DEPLOY_DIRECTORY"'; fi ;
          cp -r '"$DEPLOY_DIRECTORY"'_tmp '"$DEPLOY_DIRECTORY"' ;
          cd '"$DEPLOY_DIRECTORY"' ;
          docker-compose up -d --remove-orphans ;
          docker-compose exec -T php phing app-deploy -Dsymfony.env=prod ;
          rm -rf '"$DEPLOY_DIRECTORY"'_tmp'
    tags:
      - executor-docker


Даунтайм сейчас - это 1-2-3 минуты. Начинается он с docker-compose down ... и до
конца выполнения скрипта. Хочется его уменьшить.

А как сделать так, чтобы "мусорные" образы docker не появлялись - я вообще не понял.
Про docker image prune знаю, хочется не очищать, а не захламлять.

UPD1:

Файл docker-compose.yml создаётся следующей конструкцией:

.template-docker-compose: &docker-compose
    stage: build
    image: covex/docker-compose:1.0
    script:
      - for name in `env | awk -F= '{if($1 ~ /'"$ENV_SUFFIX"'$/) print $1}'`; do
          eval 'export '`echo $name|awk -F''"$ENV_SUFFIX"'$' '{print $1}'`'='$"$name"'';
        done
      - mkdir build
      - docker-compose -f docker-compose-deploy.yml config > build/docker-compose.yml
      - sed -i 's/\/builds\/'"$CI_PROJECT_NAMESPACE"'\/'"$CI_PROJECT_NAME"'/\./g'
build/docker-compose.yml
      - cp -R docker build
    artifacts:
        untracked: true
        name: "$CI_COMMIT_REF_NAME"
        paths:
          - build/
    tags:
      - executor-docker


В результате этой процедуры получается такой docker-compose.yml:

networks:
  nw_external:
    external:
      name: graynetwork
  nw_internal: {}
services:
  mysql:
    build:
      context: ./docker/mysql
    environment:
      MYSQL_DATABASE: project
      MYSQL_PASSWORD: project
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: project
    expose:
    - '3306'
    networks:
      nw_internal: null
    restart: always
    volumes:
    - database:/var/lib/mysql:rw
  nginx:
    build:
      args:
        app_php: app
        server_name: project-dev1.ru
      context: ./docker/nginx
    depends_on:
      php:
        condition: service_started
    networks:
      nw_external:
        ipv4_address: 192.168.10.13
      nw_internal: null
    ports:
    - 80/tcp
    restart: always
    volumes_from:
    - service:php:ro
  php:
    depends_on:
      mysql:
        condition: service_healthy
    environment:
      ENV_database_host: mysql
      ENV_database_name: project
      ENV_database_password: project
      ENV_database_port: '3306'
      ENV_database_user: project
      ENV_mailer_from: andrey@mindubaev.ru
      ENV_mailer_host: 127.0.0.1
      ENV_mailer_password: 'null'
      ENV_mailer_transport: smtp
      ENV_mailer_user: 'null'
      ENV_secret: ThisTokenIsNotSoSecretChangeIt
    expose:
    - '9000'
    image: gitlab.site.ru:5005/dev1-projects/symfony:master
    networks:
      nw_internal: null
    restart: always
    volumes:
    - /composer/vendor
    - /srv
version: '2.1'
volumes:
  database: {}


Dockerfile для сервиса nginx

FROM nginx:alpine
ARG server_name=docker.local
ARG app_php=app_dev

COPY ./default.conf /etc/nginx/conf.d/default.conf

RUN sed -i 's/@SERVER_NAME@/'"$server_name"'/g' /etc/nginx/conf.d/default.conf \
    && sed -i 's/@APP@/'"$app_php"'/g' /etc/nginx/conf.d/default.conf


Dockerfile для сервиса mysql

FROM mysql:5.7

HEALTHCHECK CMD mysqladmin ping --silent

    


Ответы

Ответ 1



Нужно минимум два контейнера, которые будет zero downtime. Дальше процесс (хорошо описан тут): остановить один старый, запустиить один новый и так по очереди. Но я буквально пару недель назад все это проходил и docker swarm это ОЧЕНЬ ПРОСТО, там пару команд, рецепт по ссылке в несколько раз сложнее. Для своего решения нужно настраивать балансировщик, а в docker swarm уже все есть и ставиться, ещё раз скажу, ОЧЕНЬ ПРОСТО. Переходите сразу на docker swarm. Он очень быстро настраивается и нулевой downtime из коробки. Просто docker service отличный инструмент, а docker stack вообще бомба (как раз поднимает все оружение из docker-compose подобного файла).

Ответ 2



Я существенно уменьшил downtime при деплое изменений на удалённый сервер, используя совет @alexes! Теперь downtime длится где-то около 5 секунд. Точнее, 5 секунд длится перезагрузка контейнера nginx и проверка обновлений для контейнеров nginx и mysql. А т.к. эта операция по большому счёту не обязательная, то downtime можно избежать вообще. В данный момент на удалённый сервер копируется только файл docker-compose.yml, все сервисы в этом файле используют уже готовый образ image, вместо build. Эти образы подготавливаются до внедрения приложения на сервер. Вместо одного сервиса с php-кодом, сейчас используется два абсолютно одинаковых: php и spare. Также операции по подготовке кэша приложения Symfony (cache:warmup) и статичных файлов подключаемых модулей bundles (assets:install) сейчас производятся в процессе подготовки образа приложения. В итоге, процедура деплоя получилась следующей: Загружаем новые образы всего приложения Обновляем и перезапускаем контейнер spare Обновляем статичные файлы Вносим изменения в структуру БД Обновляем и перезапускаем контейнер php Перезапускаем контейнер nginx docker-compose pull docker-compose up -d --no-recreate docker-compose up -d --force-recreate --no-deps spare docker-compose exec -T spare sh -c "cd /srv && rm -rf b/* && cp -a web/. b/ && rm -rf a/* && cp -a web/. a/" docker-compose exec -T spare phing storage-prepare database-deploy docker-compose up -d --force-recreate --no-deps php docker-compose stop nginx docker-compose up -d nginx Эту процедуру можно запускать как для инициализации, так и для обновления приложения. Конфигурация nginx. Здесь оба контейнера включены в upstream. Когда один из них становится недоступным во время обновления, он временно исключается из upstream самим nginx. Конструкция try_files /a$uri /b$uri /web$uri /app.php$is_args$args; позволяет отдавать правильные статичные файлы во время деплоя. upstream backend { server php:9000 fail_timeout=5s; server spare:9000 fail_timeout=5s; } server { listen 80 default_server; root /srv/web; server_name site.ru; charset utf-8; location / { root /srv; try_files /a$uri /b$uri /web$uri /app.php$is_args$args; } location ~ ^/app\.php(/|$) { fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_pass backend; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /srv/web$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT /srv/web; internal; } location /upload/ { root /srv/storage; } location ~ \.php$ { return 404; } sendfile off; client_max_body_size 100m; error_log /var/log/nginx/error.log error; } Новый файл docker-compose.yml networks: nw_external: external: name: graynetwork nw_internal: {} services: mysql: environment: MYSQL_DATABASE: project MYSQL_PASSWORD: project MYSQL_ROOT_PASSWORD: root MYSQL_USER: project expose: - '3306' image: covex/mysql:5.7 networks: nw_internal: null restart: always volumes: - database:/var/lib/mysql:rw nginx: depends_on: mysql: condition: service_healthy image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2/nginx:master networks: nw_external: ipv4_address: 192.168.10.13 nw_internal: null ports: - 80/tcp restart: always volumes: - assets:/srv/a:ro - assets:/srv/b:ro - assets:/srv/storage:ro php: environment: ENV_database_host: mysql ENV_database_mysql_version: '5.7' ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2:master networks: nw_internal: null restart: always volumes: - assets:/srv/a:rw - assets:/srv/b:rw - assets:/srv/storage:rw spare: environment: ENV_database_host: mysql ENV_database_mysql_version: '5.7' ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2:master networks: nw_internal: null restart: always volumes: - assets:/srv/a:rw - assets:/srv/b:rw - assets:/srv/storage:rw version: '2.1' volumes: assets: {} database: {}

Ответ 3



Я использую команду без downtime: docker-compose up -d --no-deps --build Пример: docker-compose up -d --no-deps --build nginx

пятница, 12 июля 2019 г.

Настройка авторизации через GitLab

Здравствуйте, такой вопрос.
Разворачиваю локально ReadTheDocs у себя на компьютере. Все поставилось и работает.
В ReadTheDosc есть функция подключение аккаунтов:
Нужно настроить подключение для гитлаба. Но выползает ошибка:
DoesNotExist at /accounts/gitlab/login/ SocialApp matching query does not exist.
Нужно объявить подключение в Django.
Захожу в настройки:
Искал долго ID и секретный ключ от Gitlaba, но так и не нашел.
Если не сложно, подскажите где посмотреть данную информацию.
Ps делаю по примеру для фейсбука: видос


Ответ

Пока что пришел к такому, что нужно зайти в настройки аккаунта на GitLab

Имя вводим какое вам угодно, URL указываем ваш. В моем случае это
http://127.0.0.1:8000/
После чего выбираем права доступа, жмем сохранить.
Нам выскакивает такой окошко, где будет указан ID и секретный ключ. (Обрезал в целях безопасности)

Но осталась проблема, что не идет авторизация, выдает ошибку так же. Если поставить обращение к example.com в категории сайт:
То выдает следующее:
Это уже ближе к истине.

понедельник, 8 июля 2019 г.

Проверка коммита на сервере GitLab Community

Проблема в следующем: Заказчик использует GitLab Community в качестве git сервера. Надо запретить push на сервер коммитов, в которых коментарий не содержит номер таска из джиры (формат например: #JIRA-1234). В какую сторону копать? Заранее спасибо.


Ответ

Нужно использовать git hook, проверяющий сообщение коммита.
Как написать хук post-receive
Полная инструкция с примерами есть в документации git.
Кратко: хук получит на вход строку вроде
ab3c291835832c309 b2fed56890cab348 new-branch
В ней:
Хеш предыдущего коммита Хеш нового коммита Название ветки, которую вы запушили на сервер
Имея хеш нового коммита, вы можете получить его сообщение, чтобы проверить его регулярным выражением.
Если оно соответствует требованиям, хук должен вернуть 0, если нет — 1
Как установить его в GitLab
Для установки хука на сервер GitLab нужны права администратора.
Кратко:
Открыть директорию /var/opt/gitlab/git-data/repositories//.git Создать в ней директорию custom_hooks/ А в ней файл pre-receive (это полное имя, расширение не нужно.) Выдайте этому файлу права на выполнение:
chmod +x /var/opt/gitlab/git-data/repositories//.git/custom_hooks/pre-receive Содержимое этого файла — код на любом интерпретируемом языке (bash, python, ruby...), который есть в системе.
Подробная инструкция по установке в GitLab: https://docs.gitlab.com/ce/administration/custom_hooks.html#setup
Пример хука post-receive
Вот подходящий пример хука (источник). Есть также статья от автора хука, объясняющая его работу.
За проверку коммита отвечает вот эта строка:
match = re.search(r'TICKET-[0-9]{2,5}|#TICKET-[0-9]{2,5}|HOTFIX|FORCE', rev)
Соответственно, вам нужно её поменять так, чтобы вместо TICKET был буквенный код проекта в джире (явно это не JIRA).
Смысл HOTFIX и FORCE в том, что иногда бывают коммиты, не принадлежащие ни к какой задаче. Просто нашли ошибку и быстро исправили. Если не предусмотреть такие «волшебные слова», то придётся заводить по задаче на каждую опечатку в комментариях. Но и злоупотреблять ими тоже не нужно.
Код полностью:
#!/bin/python import sys import re import subprocess
#Format: "oldref newref branch" line = sys.stdin.read() (base, commit, ref) = line.strip().split() new_branch_push = re.match(r'[^1-9]+', base) branch_deleted = re.match(r'[^1-9]+', commit) contains_commit_msg = False if not new_branch_push: revs = base + "..." + commit proc = subprocess.Popen(['git', 'rev-list','--oneline','--first-parent', revs], stdout=subprocess.PIPE) lines = proc.stdout.readlines() if lines: for line in lines: rev = str(line) match = re.search(r'TICKET-[0-9]{2,5}|#TICKET-[0-9]{2,5}|HOTFIX|FORCE', rev) if match is not None: contains_commit_msg = True if contains_commit_msg or new_branch_push or branch_deleted: exit(0) else: print "Commit does not contain the story associated with the commit in the format: TICKET-123 or #TICKET-123" exit(1)

Как развернуть GitLab runner с Docker executor, используя DebOps?

Хочу развернуть GitLab runner с Docker Executor, используя роли и скрипты от DebOps. Документация говорит, что Docker executor поддерживается. Пока что у меня получается только Shell executor. Ниже подробности.
Проект инициализировал с помощью debops-init. Из документации я сделал вывод, что я должен сам включить роль для Docker:
To use different executors like SSH or Docker, you need to provide additional configuration and ensure that required software (ssh, Docker, Docker Machine, etc.) is installed if required.
Получились такие конфиги:
ansible/inventory/hosts
[debops_all_hosts] myhost.domain.tdl ansible_ssh_host=10.11.11.11
# чтобы был докер [debops_service_docker] myhost.domain.tdl
[debops_service_gitlab_runner] myhost.domain.tdl
ansible/inventory/group_vars/all/all.yml
gitlab_runner__api_url: 'http://gitlab.domain.tld/ci' gitlab_runner__executor: 'docker'
Выполнил следующее:
# настройка авторизации debops bootstrap -u root --ask-pass # базовая конфигурация и докер debops
# потом раскомментировал в инвентаре [debops_service_gitlab_runner] GITLAB_RUNNER_TOKEN=mytokenhere debops service/gitlab_runner
В результате в GitLab появился подключенный раннер с Shell executor. Он работает, в логах сборки вижу "Using Shell executor...".
Но я-то хочу Docker executor. Как его получить? Возможные причины:
Не установил какую-то из нужных зависимостей. Это вообще странно с ansible и DebOps, где все зависимости обычно разрешаются автоматически. Неверные значения или не хватает каких-то переменных

UPD: посмотрел в конфиги на хосте. В /etc/gitlab-runner/config.toml вижу следующее:
concurrent = 1
[[runners]] name = "myhost.domain.tdl" url = "http://gitlab.domain.tld/ci" token = "mytokenhere" executor = "shell" [runners.docker] image = "debian" privileged = false disable_cache = false cap_drop = [ "NET_ADMIN", "SYS_ADMIN", "DAC_OVERRIDE" ]
Почему executor = "shell"?


Ответ

В роли есть такие переменные:
List of default GitLab Runner instances.
gitlab_runner__default_instances: [ '{{ gitlab_runner__instance_shell }}' ]
The default GitLab Runner instance.
gitlab_runner__instance_shell: name: '{{ gitlab_runner__fqdn }}' executor: 'shell'
Роль уcтроена таким образом, что gitlab_runner__executor имеет значение только, если не указан executor у конкретного runner'а.
Список runner'ов для конфига берется так:
for runner in (gitlab_runner__default_instances + gitlab_runner__instances + gitlab_runner__group_instances + gitlab_runner__host_instances)
Т.е. чтобы добиться эффекта, нужно, к примеру, переопределить:
gitlab_runner__default_instances: - name: '{{ gitlab_runner__fqdn }}'
и не указывать executor и тогда будет использован gitlab_runner__executor, либо явно указать:
gitlab_runner__default_instances: - name: '{{ gitlab_runner__fqdn }}' executor: docker
P.S. я это не тестировал – ответ написал, глядя в документацию и код.

пятница, 14 июня 2019 г.

Можно ли с помощью Gitlab запустить bash-скрипт на сервере?

В целом задача проста и понятна. Нужно чтобы при пуше в ветку мастер на сервере запускался один bash-скрипт, при пуше в ветку qa - другой. Можно ли это реализовать средствами gitlab? (!Важно - не веб-хуком). Если да то как? Опишите что за чем делать. Если нет, то каким способом это можно сделать?


Ответ

Запускать разные скрипты для ветки master и для всех остальных можно с помощью директив except и only. Вот пример файла .gitlab-ci.yml
image: ...
stages: - build
build_branch: stage: build script: - ./build_branch.sh except: - master
build_master: stage: build script: - ./build_master.sh only: - master

вторник, 11 июня 2019 г.

Gitlab / You have not accepted the license agreements of the following SDK component

При сборке проекта по автоматическому файлу .gitlab-ci.yml для android.
You have not accepted the license agreements of the following SDK components: [ConstraintLayout for Android 1.0.2, Solver for ConstraintLayout 1.0.2]. Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager. .gitlab-ci.yml
# This file is a template, and might need editing before it works on your project. # Read more about this script on this blog post https://about.gitlab.com/2016/11/30/setting-up-gitlab-ci-for-android-projects/, by Greyson Parrelli image: openjdk:8-jdk
variables: ANDROID_COMPILE_SDK: "26" ANDROID_BUILD_TOOLS: "26.0.1" ANDROID_SDK_TOOLS: "24.4.1"
before_script: - apt-get --quiet update --yes - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 - wget --quiet --output-document=android-sdk.tgz https://dl.google.com/android/android-sdk_r${ANDROID_SDK_TOOLS}-linux.tgz - tar --extract --gzip --file=android-sdk.tgz - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter android-${ANDROID_COMPILE_SDK} - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter platform-tools - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter build-tools-${ANDROID_BUILD_TOOLS} - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-android-m2repository - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-google_play_services - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-m2repository - export ANDROID_HOME=$PWD/android-sdk-linux - export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/ - chmod +x ./gradlew
stages: - build - test
build: stage: build script: - ./gradlew assembleDebug artifacts: paths: - app/build/outputs/
unitTests: stage: test script: - ./gradlew test
functionalTests: stage: test script: - wget --quiet --output-document=android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/0f497eb71291b52a703143c5cd63a217c8766dc9/community-cookbooks/android-sdk/files/default/android-wait-for-emulator - chmod +x android-wait-for-emulator - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter sys-img-x86-google_apis-${ANDROID_COMPILE_SDK} - echo no | android-sdk-linux/tools/android create avd -n test -t android-${ANDROID_COMPILE_SDK} --abi google_apis/x86 - android-sdk-linux/tools/emulator64-x86 -avd test -no-window -no-audio & - ./android-wait-for-emulator - adb shell input keyevent 82 - ./gradlew cAT


Ответ

На данный момент Google рекомендует такой способ:
запускаете на обычной машине с установленным Android SDK в папке проекта ./gradlew build содержимое $ANDROID_HOME/lisenses помещаете в соответствующую папку на билд-машине (у меня там android-sdk-license и android-sdk-preview-license)
В вашем случае можно положить эти файлы в репозиторий (например, в папку sdk-licenses) и добавить mkdir -p $ANDROID_HOME/licenses/ && cp sdk-licenses/* $ANDROID_HOME/licenses/ в before_script
UPDATE: в репозитории не должно быть файла local.properties, потому что параметр sdk.dir в нем имеет приоритет над $ANDROID_HOME для Gradle.

среда, 22 мая 2019 г.

Как git работает со ссылками

Здравствуйте. Мне нужно завести проект в gitlab. В проекте есть symlink'и как на директории так и на файлы. Мой вопрос такой, как git работает со ссылками? Имеет ли значение идет ссылка на файл или директорию? Если я хочу добавить их в .gitignore, мне просто добавлять их как конкретные файлы?


Ответ

git сохраняет symlink так же как файл в blob. При checkout он создаст его как symlink и не важно есть ли оригинальный файл/директория.
Вы можете добавить их в .gitignore как простые файлы по имени.

четверг, 21 марта 2019 г.

Как правильно использовать GitLab.com?

Выбрали для совместной деятельности GitLab.com, но это первый наш опыт совместного ведения проекта. Как грамотней использовать GitLab.com: с одним общим аккаунтом или создавать для каждого свой?
У нас сейчас вариант 1, но хотим уточнить, правильно ли мы понимаем вариант 2. Может есть ещё варианты?


Ответ

Я тоже работаю с GitLab. Мы сделали один аккаунт, чисто для хранения наших проектов. Естественно, закрытый. Каждый отдельный разработчик создает свой аккаунт отдельно. Затем, кто-то из вас расшаривает доступ к главному аккаунту(где лежит ваш проект) для всех разработчиков. Вы создаете свои дочерние ветки, куда вносите свои изменения, а потом кто-то заливает их в главную. Вот и все, собственно. Не говорю, что это правильно, но мы так работаем.

понедельник, 4 марта 2019 г.

Gitlab pages для своего Gitlab

Gitlab pages позволяет публиковать index.html туда.
Есть свой развернутый GitLab последней версии. что мне нужно делать, чтобы я смог использовать свой основной DNS и опубликовал также сайт?


Ответ

Нужно установить и запустить GitLab Pages daemon — это их собственный вебсервер. Он может быть установлен как на одном хосте с гитлабом, так и на отдельном.
Поставляется он в пакете Omnibus или отдельно.
Подробные инструкции есть в GitLab Pages configuration
Также можно установить и сконфигурировать с помощью роли Ansible debops.ansible-gitlab

вторник, 27 ноября 2018 г.

Cкачать (fetch) с GitLab содержимое запроса на слияние (merge request)

Сервер Gitlab, организую работу через запросы на слияние (merge request, pull request).
При создании запроса хотелось бы иметь URL, из которого Jenkins смог бы выкачивать последний коммит ветки, которая предлагается к слиянию.
Есть ли возможность в Gitlab получить такой URL?
какой-нибудь alias к ветке, предлагаемой к слиянию? автоматически создаваемый предварительный коммит? (т.е. что бы получилось, если прямо сейчас нажать кнопку Merge Request?
Знаю, что-то подобное возможно в Gitlab CI и GitHub CI, на этих коммитах даже тесты прогоняются. Поэтому возможен и третий вариант:
Работать с Jenkins как с Gitlab CI?
Перейти полностью на Gitlab CI - не вариант, это будут неоправданные затраты.


Ответ

автоматически создаваемый предварительный коммит? (т.е. что бы получилось, если прямо сейчас нажать кнопку Merge Request?
Фича пока не реализована, можно проголосовать.
какой-нибудь alias к ветке, предлагаемой к слиянию?
Реализовано. На каждый merge request гитлаб создаёт внутри себя отдельный указатель в refs/merge-requests. Нужно просто настроить свой репозиторий, чтобы при git fetch забирать эти указатели.
Открываем .git/config, находим в нём блок, соответствующий репозиторию.
[remote "origin"] url = https://gitlab.com/gitlab-org/gitlab-ce.git fetch = +refs/heads/*:refs/remotes/origin/* Добавляем в него строку +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*. Теперь должно выглядеть так:
[remote "origin"] url = https://gitlab.com/gitlab-org/gitlab-ce.git fetch = +refs/heads/*:refs/remotes/origin/* fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/* Обновляем данные:
$ git fetch origin From https://gitlab.com/gitlab-org/gitlab-ce.git * [new ref] refs/merge-requests/1/head -> origin/merge-requests/1 * [new ref] refs/merge-requests/2/head -> origin/merge-requests/2 Теперь можно создать новую локальную ветку, отслеживающую соответствующий merge request.
$ git checkout merge-requests/1 Branch merge-requests/1 set up to track remote branch merge-requests/1 from origin. Switched to a new branch 'merge-requests/1'
Примеры взяты из документации GitLab. Там же есть более подробные инструкции.

Как правильно задать редактор?

Вот я работаю с терминалом и когда хочу поверить изменения в гит
git diff
то он все показывает в терминале
я так понял, что с помощью команды
git config --global core.editor "kate"
можно установить редактор который будет показывать внесенные изменения
kate - это название редактора
После того как я выполнил эту команду я проверил файл .gitconfig и там это отобразилось
[user] name = aleksey email = aleksey@gmail.com [core] autocrlf = input excludesfile = /home/aleksey/.gitexcludes editor = kate
В последней строчке.
Но все равно когда я в терминале набираю git diff все открывается в терминале...
Подскажите как это исправить?


Ответ

Нет, не совсем правильно
Редактор git — это тот редактор, которым вы пишете сообщения коммитов. То есть сейчас если вы запустите git commit (--amend, если хотите только проверить), то у вас откроется kate для написания коммита.
Если вы хотите посмотреть изменения в каком-то графическом редакторе, то можете перенаправить системными средствами stdout в файл и открыть его каким-либо редактором *. Например:
git diff > out.txt && kate out.txt
* Тут меня должны поправить более компетентные люди, что правильнее смотреть diff-ы в difftool и соответствующих инструментах, отображающие изменения более наглядно, но я не слишком в этом компетентен.
Можно попробовать запустить git difftool --tool-help, который отобразит все возможные (и доступные) для просмотра изменений редакторы (их можно доустановить). Вот пример запуска утилиты git difftool --tool=vimdiff

Конечно же эти редакторы можно установить глобально или на проект (чтобы не писать постоянно --tool)

суббота, 13 октября 2018 г.

Как оптимизировать деплой через docker-compose?

Мы реализовали деплой через GitLab CI и docker-compose. В процессе деплоя на удалённый сервер копируется файл docker-compose.yml и файлы Dockerfile и пр. для создания "вспомогательных" контейнеров типа nginx и mysql
Всё работает как нужно. Беспокоят 2 момента: даунтайм и "мусорные" образы docker (те, что с в колонке TAG в docker images)
Вот кусок файла .gitlab-ci.yml, ответственный собственно на деплой на удалённый сервер:
.template-secure-copy: &secure-copy stage: deploy image: covex/alpine-git:1.0 before_script: - eval $(ssh-agent -s) - ssh-add <(echo "$SSH_PRIVATE_KEY") script: - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ; rm -rf '"$DEPLOY_DIRECTORY"'_tmp ; mkdir -p '"$DEPLOY_DIRECTORY"'_tmp' - scp -P 22 -r build/* ''"$DEPLOY_USER"'@'"$DEPLOY_HOST"':'"$DEPLOY_DIRECTORY"'_tmp' # */ <-- в оригинале строка не закоментирована =) - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ; cd '"$DEPLOY_DIRECTORY"'_tmp ; docker login -u gitlab-ci-token -p '"$CI_JOB_TOKEN"' '"$CI_REGISTRY"' ; docker-compose pull ; if [ -d '"$DEPLOY_DIRECTORY"' ]; then cd '"$DEPLOY_DIRECTORY"' && docker-compose down --rmi local && rm -rf '"$DEPLOY_DIRECTORY"'; fi ; cp -r '"$DEPLOY_DIRECTORY"'_tmp '"$DEPLOY_DIRECTORY"' ; cd '"$DEPLOY_DIRECTORY"' ; docker-compose up -d --remove-orphans ; docker-compose exec -T php phing app-deploy -Dsymfony.env=prod ; rm -rf '"$DEPLOY_DIRECTORY"'_tmp' tags: - executor-docker
Даунтайм сейчас - это 1-2-3 минуты. Начинается он с docker-compose down ... и до конца выполнения скрипта. Хочется его уменьшить.
А как сделать так, чтобы "мусорные" образы docker не появлялись - я вообще не понял. Про docker image prune знаю, хочется не очищать, а не захламлять.
UPD1:
Файл docker-compose.yml создаётся следующей конструкцией:
.template-docker-compose: &docker-compose stage: build image: covex/docker-compose:1.0 script: - for name in `env | awk -F= '{if($1 ~ /'"$ENV_SUFFIX"'$/) print $1}'`; do eval 'export '`echo $name|awk -F''"$ENV_SUFFIX"'$' '{print $1}'`'='$"$name"''; done - mkdir build - docker-compose -f docker-compose-deploy.yml config > build/docker-compose.yml - sed -i 's/\/builds\/'"$CI_PROJECT_NAMESPACE"'\/'"$CI_PROJECT_NAME"'/\./g' build/docker-compose.yml - cp -R docker build artifacts: untracked: true name: "$CI_COMMIT_REF_NAME" paths: - build/ tags: - executor-docker
В результате этой процедуры получается такой docker-compose.yml
networks: nw_external: external: name: graynetwork nw_internal: {} services: mysql: build: context: ./docker/mysql environment: MYSQL_DATABASE: project MYSQL_PASSWORD: project MYSQL_ROOT_PASSWORD: root MYSQL_USER: project expose: - '3306' networks: nw_internal: null restart: always volumes: - database:/var/lib/mysql:rw nginx: build: args: app_php: app server_name: project-dev1.ru context: ./docker/nginx depends_on: php: condition: service_started networks: nw_external: ipv4_address: 192.168.10.13 nw_internal: null ports: - 80/tcp restart: always volumes_from: - service:php:ro php: depends_on: mysql: condition: service_healthy environment: ENV_database_host: mysql ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt expose: - '9000' image: gitlab.site.ru:5005/dev1-projects/symfony:master networks: nw_internal: null restart: always volumes: - /composer/vendor - /srv version: '2.1' volumes: database: {}
Dockerfile для сервиса nginx
FROM nginx:alpine ARG server_name=docker.local ARG app_php=app_dev
COPY ./default.conf /etc/nginx/conf.d/default.conf
RUN sed -i 's/@SERVER_NAME@/'"$server_name"'/g' /etc/nginx/conf.d/default.conf \ && sed -i 's/@APP@/'"$app_php"'/g' /etc/nginx/conf.d/default.conf
Dockerfile для сервиса mysql
FROM mysql:5.7
HEALTHCHECK CMD mysqladmin ping --silent


Ответ

Нужно минимум два контейнера, которые будет zero downtime. Дальше процесс (хорошо описан тут): остановить один старый, запустиить один новый и так по очереди.
Но я буквально пару недель назад все это проходил и docker swarm это ОЧЕНЬ ПРОСТО, там пару команд, рецепт по ссылке в несколько раз сложнее. Для своего решения нужно настраивать балансировщик, а в docker swarm уже все есть и ставиться, ещё раз скажу, ОЧЕНЬ ПРОСТО.
Переходите сразу на docker swarm. Он очень быстро настраивается и нулевой downtime из коробки.
Просто docker service отличный инструмент, а docker stack вообще бомба (как раз поднимает все оружение из docker-compose подобного файла).

пятница, 12 октября 2018 г.

Gitlab CI / Получить только apk

При сборке проекта можно скачать архив, но apk лежит в:
Artifact/app/build/outputs/apk/debug/
Как можно получать сразу apk?
Мой файл .gitlab-ci.yml
# This file is a template, and might need editing before it works on your project. # Read more about this script on this blog post https://about.gitlab.com/2016/11/30/setting-up-gitlab-ci-for-android-projects/, by Greyson Parrelli image: openjdk:8-jdk
variables: ANDROID_COMPILE_SDK: "25" ANDROID_BUILD_TOOLS: "24.0.0" ANDROID_SDK_TOOLS: "24.4.1"
before_script: - apt-get --quiet update --yes - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 - wget --quiet --output-document=android-sdk.tgz https://dl.google.com/android/android-sdk_r${ANDROID_SDK_TOOLS}-linux.tgz - tar --extract --gzip --file=android-sdk.tgz - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter android-${ANDROID_COMPILE_SDK} - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter platform-tools - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter build-tools-${ANDROID_BUILD_TOOLS} - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-android-m2repository - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-google_play_services - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-m2repository - export ANDROID_HOME=$PWD/android-sdk-linux - export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/ - chmod +x ./gradlew - mkdir -p $ANDROID_HOME/licenses/ && cp sdk-licenses/* $ANDROID_HOME/licenses/
stages: - build
build: stage: build script: - ./gradlew assembleDebug artifacts: paths: - app/build/outputs/
Строкой - app/build/outputs/apk/debug/app-debug.apk я получаю zip архив с единственным файлом app-debug.apk. Но мне нужно только apk без /app/build/outputs/apk/debug/ можно в архиве или только apk.


Ответ

Вы можете просто скопировать его - описав скрипт с копированием. В вашем случае так например:
script: ./gradlew assembleDebug; mv app/build/outputs/apk/app-debug.apk [ожидаемое_расположение]
, где [ожидаемое_расположение] - тот путь где вы хотите сохранить app-debug.apk после сборки.