Semaphore/.circleci/config.yml
2020-11-23 23:09:55 +05:00

292 lines
8.0 KiB
YAML

# Workflow based configuration
version: 2
aliases:
# - &get-code
# run:
# name: Get code
# command: |
# git clone -b $CIRCLE_BRANCH https://github.com/ansible-semaphore/semaphore.git ./
- &golang-image
image: circleci/golang:1.15.5
- &working-dir
/go/src/github.com/ansible-semaphore/semaphore
- &store-bin-artifacts
store_artifacts:
path: /go/src/github.com/ansible-semaphore/semaphore/bin
- &install-task-binary
run:
name: install task binary
# subshell prevents potentially unwanted cwd change
command: (cd $HOME && (curl -sL https://taskfile.dev/install.sh | sh))
- &persist-from-build
persist_to_workspace:
root: .
paths:
- bin/*
- &install-node
run:
name: Install node
command: |
set +e
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install 12.15.0 && nvm alias default 12.15.0
# Each step uses the same `$BASH_ENV`, so need to modify it
echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
- &unlock-gpg
run:
name: unlock gpg key, trying to do this in the goreleaser step with env vars does not seem to work
command: |
echo $GPG_KEY | tr " " "\n" | base64 -d | gpg --import --batch
gpg --sign -u "8CDE D132 5E96 F1D9 EABF 17D4 2C96 CF7D D27F AB82" --pinentry-mode loopback --yes --batch --passphrase "${GPG_PASS}" --output unlock.sig --detach-sign README.md
rm -f unlock.sig
- &test-compile-changes
run:
name: test that compile did not create/modify untracked files
command: git diff --exit-code --stat -- . ':(exclude)web2/package-lock.json' ':(exclude)web/package-lock.json' ':(exclude)go.mod' ':(exclude)go.sum'
- &save-npm-cache
save_cache:
key: v1-npm-deps-{{ checksum "web/package.json" }}
paths:
- web/node_modules
- &save-go-cache
save_cache:
key: v1-go-deps-{{ checksum "go.sum" }}-{{ checksum "go.mod" }}
paths:
- vendor
- &load-npm-cache
restore_cache:
keys:
- v1-npm-deps-{{ checksum "web/package.json" }}
- v1-npm-deps-
- &load-go-cache
restore_cache:
keys:
- v1-go-deps-{{ checksum "go.sum" }}-{{ checksum "go.mod" }}
- v1-go-deps-{{ checksum "go.sum" }}
- v1-go-deps-
jobs:
build:local:
docker:
- *golang-image
working_directory: *working-dir
steps:
- *install-node
- *install-task-binary
- checkout
- *load-go-cache
- *load-npm-cache
- run: task deps
- *save-go-cache
- *save-npm-cache
- run: task compile
- *test-compile-changes
- run: task build:local
- *store-bin-artifacts
- *persist-from-build
build:
docker:
- *golang-image
working_directory: *working-dir
steps:
- *install-node
- *install-task-binary
- run: sudo apt-get install rpm
- checkout
- *load-go-cache
- *load-npm-cache
- run: task deps
- run: task compile
- *test-compile-changes
- *unlock-gpg
- run: task build
- *store-bin-artifacts
test:integration:hooks:
docker:
- *golang-image
working_directory: *working-dir
steps:
- checkout
- *install-node
- *install-task-binary
- run: task deps:integration
- run: task deps:tools
- run: task deps:be
- run: task compile:be
- run: task compile:api:hooks
- store_artifacts:
path: /go/src/github.com/ansible-semaphore/semaphore/.dredd/compiled_hooks
# Run goverage and post results
test:golang:
docker:
- *golang-image
working_directory: *working-dir
steps:
- *install-task-binary
# Needed only in ci to post coverage reports
- run: go get github.com/schrej/godacov
- checkout
- *load-go-cache
- run: task deps:tools
- run: task deps:be
- run: task compile:be
- run: task lint:be
- run: task test
- run: godacov -t "${CODACY_TOKEN}" -r ./coverage.out -c "${CIRCLE_SHA1}" || true
- store_test_results:
path: /go/src/github.com/ansible-semaphore/semaphore/coverage.out
- store_artifacts:
path: /go/src/github.com/ansible-semaphore/semaphore/coverage.out
test:integration:
machine: true
steps:
- checkout
- *install-task-binary
- run: context=ci task dc:up
test:db:migration:
docker:
- *golang-image
- image: circleci/mysql:5.6
working_directory: *working-dir
steps:
- *install-task-binary
- *install-node
- attach_workspace:
at: *working-dir
# This looks like utter filth in circleci v2 but we have no choice apart from this escaping madness
- run: "cat > config.json <<EOF\n{\n\t\"mysql\": {\n\t\t\"host\": \"127.0.0.1:3306\"\
,\n\t\t\"user\": \"root\",\n\t\t\"pass\": \"\",\n\t\t\"name\": \"circle_test\"\
\n\t},\n\t\"email_alert\": false\n}\nEOF\n"
- run:
name: Wait for db
command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
- run: bin/semaphore --migrate -config config.json
test:docker:
docker:
- *golang-image
steps:
- *install-task-binary
- checkout
- setup_remote_docker
- run: context=prod task docker:test
deploy:dev:
docker:
- *golang-image
steps:
- *install-task-binary
- checkout
- setup_remote_docker
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
- run: context=prod tag=develop task docker:build
- run: tag=develop task docker:push
deploy:prod:
docker:
- *golang-image
steps:
- *install-task-binary
- checkout
- setup_remote_docker
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
- run: context=prod tag=latest task docker:build
- run: tag=latest task docker:push
- run: docker tag ansiblesemaphore/semaphore:latest ansiblesemaphore/semaphore:$CIRCLE_TAG
- run: tag=$CIRCLE_TAG task docker:push
# For releases to work in the ci you will need to have the following env vars set
# GITHUB_TOKEN - token needs writes to make a release
# GPG_PASS - password for the GP key to sign releases with, circleci sets env vars with "" so be wary of special chars
# GPG_KEY - base64 encoded version of the GPG private key
release:
docker:
- *golang-image
working_directory: *working-dir
steps:
- *install-node
- *install-task-binary
- run: sudo apt-get install rpm
- checkout
- *load-go-cache
- *load-npm-cache
- run: task deps
- *unlock-gpg
- run:
name: reset repo as npm install may have changed lock file
command: git reset --hard
- run: task release:prod
- *store-bin-artifacts
workflows:
version: 2
build-test:
jobs:
- test:docker
- test:golang
- test:integration:hooks
- test:integration
- build:local
- test:db:migration:
requires:
- build:local
# Don't build on master because build is just a gorelease without the release
- build:
requires:
- test:golang
- test:db:migration
- test:integration
filters:
branches:
ignore: master
# Dev deploys require all tests to pass and app builds
- deploy:dev:
requires:
- build
- test:docker
filters:
branches:
only: develop
# Production deploys only happen if everything passes
# and we have a tag starting with v
- release:
filters:
branches:
ignore: /.*/
tags:
only: /^v.*/
- deploy:prod:
filters:
branches:
ignore: /.*/
tags:
only: /^v.*/