stages: - test - build - deploy # 1️⃣ Tests Laravel test: stage: test image: laravelsail/php84-composer variables: APP_ENV: testing APP_KEY: base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= DB_CONNECTION: sqlite DB_DATABASE: ":memory:" before_script: - apt-get update && apt-get install -y libicu-dev - docker-php-ext-configure intl && docker-php-ext-install intl - composer install --no-interaction --prefer-dist script: - php artisan test rules: - when: always # 2️⃣ Build + push image docker-build-push: stage: build image: docker:24 services: - docker:24-dind variables: DOCKER_TLS_CERTDIR: "/certs" IMAGE_TAG: "$CI_REGISTRY_IMAGE:${CI_COMMIT_SHORT_SHA}" before_script: - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY" script: - docker build -t "$IMAGE_TAG" . - docker push "$IMAGE_TAG" rules: - if: '$CI_COMMIT_BRANCH == "main"' # 3️⃣ Deploy via Portainer deploy-to-portainer: stage: deploy image: alpine:latest needs: - docker-build-push before_script: - apk add --no-cache curl jq gettext script: - envsubst < docker-compose.prod.yml > docker-compose.rendered.yml - | STACKS_JSON=$(curl -s -H "X-API-Key: $PORTAINER_API_KEY" "$PORTAINER_URL/api/stacks") STACK_ID=$(echo "$STACKS_JSON" | jq ".[] | select(.Name == \"$PORTAINER_STACK_NAME\") | .Id") STACK_FILE_PATH="docker-compose.rendered.yml" if [ -z "$STACK_ID" ]; then JSON_PAYLOAD=$(jq -n \ --arg name "$PORTAINER_STACK_NAME" \ --rawfile content "$STACK_FILE_PATH" \ '{name: $name, stackFileContent: $content, prune: true}') curl -s -f \ -X POST "$PORTAINER_URL/api/stacks/create/standalone/string?endpointId=$PORTAINER_ENDPOINT_ID" \ -H "X-API-Key: $PORTAINER_API_KEY" \ -H "Content-Type: application/json" \ --data "$JSON_PAYLOAD" \ > /dev/null else JSON_PAYLOAD=$(jq -n \ --arg id "$STACK_ID" \ --rawfile content "$STACK_FILE_PATH" \ '{id: ($id|tonumber), stackFileContent: $content, prune: true, pullImage: true}') curl -s -f \ -X PUT "$PORTAINER_URL/api/stacks/$STACK_ID?endpointId=$PORTAINER_ENDPOINT_ID" \ -H "X-API-Key: $PORTAINER_API_KEY" \ -H "Content-Type: application/json" \ --data "$JSON_PAYLOAD" \ > /dev/null fi rules: - if: '$CI_COMMIT_BRANCH == "main"'