diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c74cbba..db9a867 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,14 +5,20 @@ build: script: - cargo-leptos build +.docker: + image: docker:latest + services: + - docker:dind + tags: + - docker + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + # Build the docker image and push it to the registry docker-build: needs: ["build"] - image: docker:latest + extends: .docker script: - - /usr/local/bin/dockerd-entrypoint.sh & - - while ! docker info; do echo "Waiting for Docker to become available..."; sleep 1; done - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA . # If running on the default branch, tag as latest - if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then docker tag @@ -44,35 +50,50 @@ cargo-doc: paths: - target/doc -.argocd: - image: argoproj/argocd:v2.6.15 - before_script: - - argocd login ${ARGOCD_SERVER} --username ${ARGOCD_USERNAME} --password ${ARGOCD_PASSWORD} --grpc-web - # Start the review environment start-review: - extends: .argocd + extends: .docker rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: manual script: - - argocd app sync argocd/libretunes-review-${CI_COMMIT_SHORT_SHA} - - argocd app wait argocd/libretunes-review-${CI_COMMIT_SHORT_SHA} + - apk add curl openssl + - cd cicd + - echo "$CLOUDFLARE_TUNNEL_AUTH_JSON" > tunnel-auth.json + - ./add-dns.sh $CLOUDFLARE_ZONE_ID review-$CI_COMMIT_SHORT_SHA libretunes-auto-review $CLOUDFLARE_API_TOKEN $CLOUDFLARE_TUNNEL_ID + - ./create-tunnel-config.sh http://libretunes:3000 review-$CI_COMMIT_SHORT_SHA.libretunes.xyz $CLOUDFLARE_TUNNEL_ID + - export COMPOSE_PROJECT_NAME=review-$CI_COMMIT_SHORT_SHA + - export POSTGRES_PASSWORD=$(openssl rand -hex 16) + - export LIBRETUNES_VERSION=$CI_COMMIT_SHORT_SHA + - docker compose --file docker-compose-cicd.yml pull + - docker compose --file docker-compose-cicd.yml create + - export CONFIG_VOL_NAME=review-${CI_COMMIT_SHORT_SHA}_cloudflared-config + - export TMP_CONTAINER_NAME=$(docker run --rm -d -v $CONFIG_VOL_NAME:/data busybox sh -c "sleep infinity") + - docker cp tunnel-auth.json $TMP_CONTAINER_NAME:/data/auth.json + - docker cp cloudflared-tunnel-config.yml $TMP_CONTAINER_NAME:/data/config.yml + - docker stop $TMP_CONTAINER_NAME + - docker compose --file docker-compose-cicd.yml up -d environment: name: review/$CI_COMMIT_SHORT_SHA - url: https://review-$CI_COMMIT_SHORT_SHA.libretunes.mregirouard.com + url: https://review-$CI_COMMIT_SHORT_SHA.libretunes.xyz on_stop: stop-review + auto_stop_in: 1 week # Stop the review environment stop-review: needs: ["start-review"] - extends: .argocd + extends: .docker rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: manual allow_failure: true script: - - argocd app delete argocd/libretunes-review-${CI_COMMIT_SHORT_SHA} --cascade + - apk add jq curl + - ./cicd/remove-dns.sh $CLOUDFLARE_ZONE_ID review-$CI_COMMIT_SHORT_SHA.libretunes.xyz libretunes-auto-review $CLOUDFLARE_API_TOKEN + - export COMPOSE_PROJECT_NAME=review-$CI_COMMIT_SHORT_SHA + - export LIBRETUNES_VERSION=$CI_COMMIT_SHORT_SHA + - docker compose --file cicd/docker-compose-cicd.yml down + - docker compose --file cicd/docker-compose-cicd.yml rm -f -v environment: name: review/$CI_COMMIT_SHORT_SHA action: stop diff --git a/cicd/add-dns.sh b/cicd/add-dns.sh new file mode 100755 index 0000000..7247314 --- /dev/null +++ b/cicd/add-dns.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +ZONE_ID=$1 +RECORD_NAME=$2 +RECORD_COMMENT=$3 +API_TOKEN=$4 +TUNNEL_ID=$5 + +curl --request POST --silent \ + --url https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records \ + --header 'Content-Type: application/json' \ + --header "Authorization: Bearer $API_TOKEN" \ + --data '{ + "content": "'$TUNNEL_ID'.cfargotunnel.com", + "name": "'$RECORD_NAME'", + "comment": "'$RECORD_COMMENT'", + "proxied": true, + "type": "CNAME", + "ttl": 1 +}' \ diff --git a/cicd/create-tunnel-config.sh b/cicd/create-tunnel-config.sh new file mode 100755 index 0000000..11fb59a --- /dev/null +++ b/cicd/create-tunnel-config.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +SERVICE=$1 +HOSTNAME=$2 +TUNNEL_ID=$3 + +echo "Creating tunnel config for $HOSTNAME" + +cat < cloudflared-tunnel-config.yml +tunnel: $TUNNEL_ID +credentials-file: /etc/cloudflared/auth.json + +ingress: + - hostname: $HOSTNAME + service: $SERVICE + - service: http_status:404 +EOF diff --git a/cicd/docker-compose-cicd.yml b/cicd/docker-compose-cicd.yml new file mode 100644 index 0000000..723ca41 --- /dev/null +++ b/cicd/docker-compose-cicd.yml @@ -0,0 +1,55 @@ +version: '3' + +services: + cloudflare: + image: cloudflare/cloudflared:latest + command: tunnel run + volumes: + - cloudflared-config:/etc/cloudflared:ro + + libretunes: + image: registry.mregirouard.com/libretunes/libretunes:${LIBRETUNES_VERSION} + environment: + REDIS_URL: redis://redis:6379 + POSTGRES_HOST: postgres + POSTGRES_USER: libretunes + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: libretunes + volumes: + - libretunes-audio:/site/audio + depends_on: + - redis + - postgres + restart: always + + redis: + image: redis:latest + volumes: + - libretunes-redis:/data + restart: always + healthcheck: + test: ["CMD-SHELL", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + + postgres: + image: postgres:latest + environment: + POSTGRES_USER: libretunes + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: libretunes + volumes: + - libretunes-postgres:/var/lib/postgresql/data + restart: always + healthcheck: + test: ["CMD-SHELL", "pg_isready -U libretunes"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + cloudflared-config: + libretunes-audio: + libretunes-redis: + libretunes-postgres: diff --git a/cicd/remove-dns.sh b/cicd/remove-dns.sh new file mode 100755 index 0000000..3a80869 --- /dev/null +++ b/cicd/remove-dns.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +ZONE_ID=$1 +RECORD_NAME=$2 +RECORD_COMMENT=$3 +API_TOKEN=$4 + +RECORD_ID=$( +curl --request GET --silent \ + --url "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$RECORD_NAME&comment=$RECORD_COMMENT" \ + --header "Content-Type: application/json" \ + --header "Authorization: Bearer $API_TOKEN" \ +| jq -r '.result[0].id') + +echo "Deleting DNS record ID $RECORD_ID" + +curl --request DELETE --silent \ + --url "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \ + --header "Content-Type: application/json" \ + --header "Authorization: Bearer $API_TOKEN"