add gitlab section

This commit is contained in:
kirby 2025-05-28 11:53:16 +02:00
parent e96e220869
commit 0d5f9eff7e
5 changed files with 489 additions and 0 deletions

View File

@ -0,0 +1,32 @@
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
# NO DEPLOYMENT ON CLASSICS BRANCH
- if: '$CI_COMMIT_REF_PROTECTED == "false"'
variables:
ENVIRONMENT: "null"
ENVIRONMENT_SHORT: "null"
IMAGE_TAG: $CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$IMAGE_TAG
# TESTING - develop only
- if: '$CI_COMMIT_TAG == null && $CI_COMMIT_REF_NAME == "develop" && $CI_COMMIT_REF_PROTECTED == "true"'
variables:
ENVIRONMENT: testing
ENVIRONMENT_SHORT: tst
IMAGE_TAG: $CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$IMAGE_TAG
# STAGING - main/master only
- if: '($CI_COMMIT_REF_NAME == "main" || $CI_COMMIT_REF_NAME == "master") && $CI_COMMIT_REF_PROTECTED == "true"'
variables:
ENVIRONMENT: staging
ENVIRONMENT_SHORT: stg
IMAGE_TAG: $CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$IMAGE_TAG
# PRODUCTION - tags only
- if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"'
variables:
ENVIRONMENT: production
ENVIRONMENT_SHORT: prd
IMAGE_TAG: $CI_COMMIT_TAG
CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$IMAGE_TAG

View File

@ -0,0 +1,108 @@
stages:
- init
- build
- scan
- deploy
# ###########################################
# Configuration section
# ###########################################
.helminit: &helminit
before_script:
- echo "Adding Helm repository..."
- helm repo add --username $CI_REGISTRY_USER --password $CI_JOB_TOKEN helm-charts $CI_API_V4_URL/projects/645/packages/helm/stable
- helm repo update
- echo "Validating Helm dependencies..."
- helm dependency update ./helm
# ###########################################
# Build section
# ###########################################
.build_template: &build_template
image:
name: moby/buildkit:v0.21.0
entrypoint: [""]
variables:
DOCKER_BUILDKIT: 1
before_script:
- echo "Preparing BuildKit environment..."
- mkdir -p /root/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /root/.docker/config.json
- echo "Initializing build arguments..."
- |
for VARNAME in $BUILD_ARGS; do
VALUE=$(eval echo \$$VARNAME)
BUILDPARAMS="$BUILDPARAMS --opt build-arg:$VARNAME=$VALUE"
done
echo "Build parameters: $BUILDPARAMS"
script:
- echo "Validating build context..."
- ls -la $CI_PROJECT_DIR
- echo "Starting BuildKit build with the following settings:"
- |
buildctl-daemonless.sh build --frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=${BUILD_IMAGE_DESTINATION},push=true \
--export-cache type=registry,ref=${CI_REGISTRY_IMAGE}/cache,image-manifest=true \
--import-cache type=registry,ref=${CI_REGISTRY_IMAGE}/cache \
--opt target=${BUILD_TARGET} \
${BUILDPARAMS}
.build:image:
<<: *build_template
variables:
BUILD_IMAGE_DESTINATION: $CONTAINER_IMAGE
BUILD_TARGET:
BUILD_ARGS:
# ###########################################
# Deploy section
# ###########################################
.deploy:k8s:
image: alpine/helm:3.21.0
variables:
HELM_CUSTOM_ARGS: ""
NAMESPACE: tests
HPA_REPLICAS: 1
HPA_MAXREPLICAS: 1
HELM_NAME: $CI_PROJECT_NAME
INJECT_ENVVARS_GITLAB: "false"
VALUES_ENVVARS_PATH: symfonyLib.phpfpm.envVars.
before_script:
- !reference [".helminit", before_script]
- |
if [[ "$INJECT_ENVVARS_GITLAB" == "true" ]]; then
echo "Injecting environment variables into Helm Chart..."
for VARNAME in $(env); do
if [[ $(echo $VARNAME | egrep '^ENV_') ]]; then
NAME=$(echo "$VARNAME" | cut -d"=" -f1 | sed "s/ENV_/$VALUES_ENVVARS_PATH/")
VAR=$(echo "$VARNAME" | cut -d"=" -f2-)
echo -e $NAME
ENVVARS="${ENVVARS} --set $NAME=$VAR"
fi
done
fi
script:
- echo "Validating Helm chart..."
- helm lint ./helm # Validation du chart Helm avant déploiement
- echo "Deploying to $ENVIRONMENT k8s cluster in $NAMESPACE namespace..."
- |
helm upgrade --install --namespace $NAMESPACE -f ./helm/values.yaml $HELM_CUSTOM_ARGS \
--set global.app.env="$ENVIRONMENT_SHORT" \
--set global.replica.replicaCount="$HPA_REPLICAS" \
--set global.replica.maxReplicaCount="$HPA_MAXREPLICAS" \
--set global.app.version="$IMAGE_TAG" \
--set global.namespace="$NAMESPACE" \
--set global.app.revision="$CI_COMMIT_SHORT_SHA" \
--set symfonyLib.phpfpm.image="$CI_REGISTRY_IMAGE" \
--set pythonLib.python.image="$CI_REGISTRY_IMAGE" \
$ENVVARS $HELM_NAME ./helm
- if [ $? -eq 0 ]; then touch success; fi
after_script:
- |
if [ -f 'success' ] && [ "$ENVIRONMENT" == 'production' ]; then
echo 'Sending notification to Teams webhook...'
apk add curl
curl -H 'Content-Type: application/json' -d "{\"text\": \"[prd] [job/$CI_JOB_NAME] [$CI_PROJECT_NAME] [$CI_COMMIT_REF_NAME] [$CI_PIPELINE_URL] completed!\"}" $TEAMS_WEBHOOK
fi

141
gitlab/cicd/go.yml Normal file
View File

@ -0,0 +1,141 @@
include:
- project: $TEMPLATES_PROJECT_NAME
file: 'docker-k8s-utils.yml'
ref: $TEMPLATES_DEFAULT_BRANCH
- project: $TEMPLATES_PROJECT_NAME
file: 'utils.yml'
ref: $TEMPLATES_DEFAULT_BRANCH
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
# NO DEPLOYMENT
- if: '$CI_COMMIT_TAG == null'
variables:
IMAGE_TAG: $CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$IMAGE_TAG
changes:
- app/*
- app/*/*
- Dockerfile
- .gitlab-ci.yml
# STAGING/PRODUCTION - tags only
- if: '$CI_COMMIT_TAG =~ /(alpha)|(beta)|(rc)/'
variables:
IMAGE_TAG: $CI_COMMIT_TAG
CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$IMAGE_TAG
ENVIRONMENT: 'staging'
ENVIRONMENT_SHORT: 'stg'
- if: '$CI_COMMIT_TAG'
variables:
IMAGE_TAG: $CI_COMMIT_TAG
CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$IMAGE_TAG
ENVIRONMENT: 'production'
ENVIRONMENT_SHORT: 'prd'
variables:
SRC_ROOT_PATH: "./app"
VAULT_ADDR: https://vault.example.com
stages:
- lint
- build
- test
- release
variables:checker:
extends: .variables:checker
stage: .pre
variables:
VARS_TO_CHECK_APP: ""
VARS_TO_CHECK_SYSTEM: SRC_ROOT_PATH CONTAINER_IMAGE
# ###########################################
# Lint
# ###########################################
linter:
image: golangci/golangci-lint:v2.0.2-alpine
rules:
- changes:
- .gitlab-ci.yml
- app/*
- app/*/*
when: always
stage: lint
before_script:
- cd $SRC_ROOT_PATH
script:
- go mod tidy
- golangci-lint run --output.code-climate.path gl-code-quality-report.json --path-prefix /app/
artifacts:
reports:
codequality: $SRC_ROOT_PATH/gl-code-quality-report.json
build:application_test:
extends: .build:image
stage: build
variables:
BUILD_TARGET: dev
BUILD_IMAGE_DESTINATION: ${CONTAINER_IMAGE}_dev
BUILD_ARGS: ""
#######################################
# TEST
#######################################
go:tests:
image: ${CONTAINER_IMAGE}_dev
stage: test
before_script:
- cd $SRC_ROOT_PATH
- go mod tidy
- go install github.com/jstemmer/go-junit-report@latest
- go install github.com/boumenot/gocover-cobertura@latest
script:
- echo "Execute tests"
- go test ./... -v | go-junit-report > report-gotest.xml
- echo "Compute coverage"
- go test ./... -v -coverprofile=coverage.txt -covermode count
- gocover-cobertura < coverage.txt > report-coverage.xml
coverage: '/^coverage: \d+.\d+% of statements/'
artifacts:
reports:
junit: $SRC_ROOT_PATH/report-gotest.xml
coverage_report:
coverage_format: cobertura
path: $SRC_ROOT_PATH/report-coverage.xml
#######################################
# BUILD
# #####################################
build:image:
extends: .build:image
stage: build
rules:
- if: '$CI_COMMIT_TAG'
when: on_success
variables:
BUILD_TARGET: prod
BUILD_IMAGE_DESTINATION: $CONTAINER_IMAGE
BUILD_ARGS: ""
# ###########################################
# Release
# ###########################################
release:image:
image: hashicorp/vault:1.19.3
stage: release
environment: $ENVIRONMENT
before_script:
- echo "Authentification Vault"
- export VAULT_TOKEN=$(vault write -field=token auth/approle/login role_id=$VAULT_ROLE_ID secret_id=$VAULT_SECRET_ID)
script:
- echo "Push last tag on Vault"
- vault kv put app/<myApp>/$ENVIRONMENT_SHORT/image_latest name=$CONTAINER_IMAGE
needs:
- build:image
rules:
- if: '$CI_COMMIT_TAG'
when: on_success

179
gitlab/cicd/php-symfony.yml Normal file
View File

@ -0,0 +1,179 @@
# ###########################################
# Security section
# ###########################################
.security:advisories:
image: <imageUrl>/docker/local-php-security-checker:1.0.0
allow_failure: true
script:
- cd $SRC_ROOT_PATH
- local-php-security-checker --format=junit src > ./report-security-checker.xml
artifacts:
reports:
junit: $SRC_ROOT_PATH/report-security-checker.xml
# ###########################################
# Qualimetry section
# ###########################################
.php:lint:
image: jakzal/phpqa:php${PHP_VERSION}${JAKZAL_PHP_VERSION}-alpine
script:
- cd $SRC_ROOT_PATH
- parallel-lint . --exclude vendor
.php:checkstyle:
image: jakzal/phpqa:php${PHP_VERSION}${JAKZAL_PHP_VERSION}-alpine
script:
- cd $SRC_ROOT_PATH
- phpcs --extensions=php -n --standard=PSR12 src tests --report=junit > ./report-phpcs.xml
artifacts:
reports:
junit: $SRC_ROOT_PATH/report-phpcs.xml
.php:stan:
image: jakzal/phpqa:php${PHP_VERSION}${JAKZAL_PHP_VERSION}-alpine
variables:
STAN_LEVEL: 5
script:
- echo ${STAN_LEVEL}
- cd $SRC_ROOT_PATH
- phpstan analyse src --level=$STAN_LEVEL --no-progress --error-format=junit > ./report-phpstan.xml
artifacts:
reports:
junit: $SRC_ROOT_PATH/report-phpstan.xml
# ###########################################
# Tests section
# ###########################################
.test:unit:
image: $CONTAINER_IMAGE
variables:
APP_ENV: test
XDEBUG_MODE: coverage
before_script:
- install-php-extensions xdebug-stable
- cp ./docker/env/.env.test $SRC_ROOT_PATH/.env
- cd $SRC_ROOT_PATH
- composer install --prefer-dist --no-progress --no-interaction
- bin/console cache:warmup --env=test
script:
- vendor/bin/simple-phpunit --coverage-text --colors=never --log-junit ./report-phpunit.xml
coverage: '/^\s*Lines:\s*\d+.\d+\%/'
artifacts:
reports:
junit: $SRC_ROOT_PATH/report-phpunit.xml
.test:phpunit:
image: ${CONTAINER_IMAGE}_dev
variables:
APP_ENV: test
XDEBUG_MODE: coverage
GIT_STRATEGY: none
SRC_ROOT_PATH: /app
before_script:
- cd $SRC_ROOT_PATH
# Composer setup
- composer install --prefer-dist --no-progress --no-interaction
- composer dump-autoload --classmap-authoritative
- composer dump-env test
- composer run-script post-install-cmd
script:
- cd $SRC_ROOT_PATH
- ls -la
- vendor/bin/simple-phpunit --coverage-text --colors=never --log-junit="${CI_PROJECT_DIR}"/report-phpunit.xml
coverage: '/^\s*Lines:\s*\d+.\d+\%/'
artifacts:
reports:
junit: ./report-phpunit.xml
.test:phpunit:standalone:
image: ${CONTAINER_IMAGE}_dev
variables:
APP_ENV: test
XDEBUG_MODE: coverage
GIT_STRATEGY: none
SRC_ROOT_PATH: /app
script:
- cd $SRC_ROOT_PATH
- vendor/bin/phpunit --coverage-text --colors=never --log-junit="${CI_PROJECT_DIR}"/report-phpunit.xml
coverage: '/^\s*Lines:\s*\d+.\d+\%/'
artifacts:
reports:
junit: ./report-phpunit.xml
.test:codeception:
image: ${CONTAINER_IMAGE}_dev
variables:
APP_ENV: test
XDEBUG_MODE: coverage
GIT_STRATEGY: none
SRC_ROOT_PATH: /app
before_script:
- cd $SRC_ROOT_PATH
- sed -i 's#http://web#http://127.0.0.1:80#g' $SRC_ROOT_PATH/tests/api.suite.yml
# Composer setup
- composer install --prefer-dist --no-progress --no-interaction
- composer dump-autoload --classmap-authoritative
- composer dump-env test
- composer run-script post-install-cmd
script:
- cd $SRC_ROOT_PATH && symfony local:server:start --port=80 --no-tls -d
- $SRC_ROOT_PATH/vendor/bin/codecept run --xml --coverage --coverage-text --no-colors && true; exit_code=$?
- symfony local:server:stop
- exit $exit_code
after_script:
# Copy directory to CI dir for artifacts
- cp -r $SRC_ROOT_PATH/tests $CI_PROJECT_DIR/
coverage: '/^\s*Lines:\s*\d+.\d+\%/'
artifacts:
expire_in: 1 day
when: always
paths:
- ./tests/_build/output/
reports:
junit: ./tests/_build/output/report.xml
.test:codeception:noweb:
extends: .test:codeception
before_script:
- cd $SRC_ROOT_PATH
# Composer setup
- composer install --prefer-dist --no-progress --no-interaction
- composer dump-autoload --classmap-authoritative
- composer dump-env test
- composer run-script post-install-cmd
script:
- cd $SRC_ROOT_PATH
- $SRC_ROOT_PATH/vendor/bin/codecept run --xml --coverage --coverage-text --no-colors && true; exit_code=$?
- exit $exit_code
.test:codeception5:
image: ${CONTAINER_IMAGE}_dev
variables:
APP_ENV: test
XDEBUG_MODE: coverage
GIT_STRATEGY: none
SRC_ROOT_PATH: /app
before_script:
- cd $SRC_ROOT_PATH
- sed -i 's#http://web#http://127.0.0.1:80#g' $SRC_ROOT_PATH/tests/Api.suite.yml
# Composer setup
- composer install --prefer-dist --no-progress --no-interaction
- composer dump-autoload --classmap-authoritative
- composer dump-env test
- composer run-script post-install-cmd
script:
- cd $SRC_ROOT_PATH && symfony local:server:start --port=80 --no-tls -d
- $SRC_ROOT_PATH/vendor/bin/codecept run --xml --coverage --coverage-text --no-colors && true; exit_code=$?
- symfony local:server:stop
- exit $exit_code
after_script:
# Copy directory to CI dir for artifacts
- cp -r $SRC_ROOT_PATH/tests $CI_PROJECT_DIR/
coverage: '/^\s*Lines:\s*\d+.\d+\%/'
artifacts:
expire_in: 1 day
when: always
paths:
- ./tests/_output/
reports:
junit: ./tests/_output/report.xml

29
gitlab/cicd/utils.yml Normal file
View File

@ -0,0 +1,29 @@
# Check that variables exists
.variables:checker:
variables:
VARS_TO_CHECK_SYSTEM: SRC_ROOT_PATH CONTAINER_IMAGE ENVIRONMENT ENVIRONMENT_SHORT
VARS_TO_CHECK_APP:
VARS_TO_CHECK: $VARS_TO_CHECK_SYSTEM $VARS_TO_CHECK_APP
script:
- echo "Checking of the existence of some variables..."
- |
checkVariables () {
TXT_RED="\e[91m" && TXT_GREEN="\e[92m" && TXT_CLEAR="\e[0m"
inError=0
for var in "$@"
do
echo -ne "\$${var} : "
if [ -z "${!var}" ]; then
echo -e "\xE2\x9D\x8C ${TXT_RED}not defined${TXT_CLEAR}";
inError=1;
else
echo -e "\xE2\x9C\x94 ${TXT_GREEN}defined${TXT_CLEAR}";
fi
done
return $inError
}
checkVariables $VARS_TO_CHECK
exit $?