diff --git a/.github/workflows/build-and-push-shared.yml b/.github/workflows/build-and-push-shared.yml index 7a7047ec..99813bac 100644 --- a/.github/workflows/build-and-push-shared.yml +++ b/.github/workflows/build-and-push-shared.yml @@ -80,7 +80,7 @@ jobs: - name: Set image tag output id: set-tag - run: echo "::set-output name=image-tag::${{ steps.meta.outputs.version }}" + run: echo "image-tag=${{ steps.meta.outputs.version }}" >> $GITHUB_OUTPUT - name: Build and push Docker Image uses: docker/build-push-action@v6 diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index 59c1b95a..5b2a4b9d 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -1,21 +1,32 @@ -name: Deploy Dev +name: Deploy to Dev on: workflow_dispatch: inputs: image-tag: type: string - description: "The tag of the docker images to deploy" - required: true -jobs: + description: "Image tag to deploy (default: pr- if PR exists, latest for default branch)" + +jobs: + prepare-env: + runs-on: ubuntu-latest + environment: Dev + outputs: + env-vars: | + DEPLOYMENT_URL=${{ vars.DEPLOYMENT_URL }} + APOLLON_REDIS_DIAGRAM_TTL=${{ vars.APOLLON_REDIS_DIAGRAM_TTL }} + steps: + - name: Do nothing + run: echo "Nothing to do here" + deploy: + needs: prepare-env # TODO: uses: ls1intum/.github/.github/workflows/deploy-docker-compose.yml@main uses: ./.github/workflows/deploy-docker-compose-shared.yml with: environment: Dev docker-compose-file: "./docker-compose.prod.yml" + main-image-name: ls1intum/apollon_standalone image-tag: ${{ inputs.image-tag }} - env-vars: | - DEPLOYMENT_URL=${{ vars.DEPLOYMENT_URL }} - APOLLON_REDIS_DIAGRAM_TTL=${{ vars.APOLLON_REDIS_DIAGRAM_TTL }} + env-vars: ${{ needs.prepare-env.outputs.env-vars }} secrets: inherit diff --git a/.github/workflows/deploy-docker-compose-shared.yml b/.github/workflows/deploy-docker-compose-shared.yml index a5e2827c..76821c14 100644 --- a/.github/workflows/deploy-docker-compose-shared.yml +++ b/.github/workflows/deploy-docker-compose-shared.yml @@ -12,25 +12,77 @@ on: type: string default: "./docker-compose.yml" description: "Path to the Docker Compose file (Default: ./docker-compose.yml)" + main-image-name: + type: string + description: "The name of the main image for checking if it exists with the given tag" + required: true image-tag: type: string - default: latest - description: "Tag of the Docker images to deploy (Default: latest)" + description: "Image tag to deploy (default: pr- if PR exists, latest for default branch)" env-vars: type: string description: "Additional environment variables in KEY=VALUE format, separated by newlines" required: false jobs: + prepare-deploy: + runs-on: ubuntu-latest + environment: Dev + outputs: + image-tag-to-deploy: ${{ steps.retrieve-image-tag.outputs.image-tag-to-deploy }} + + steps: + - name: Retrieve image tag to deploy + id: retrieve-image-tag + run: | + if [ -n "${{ inputs.image-tag }}" ]; then + echo "image-tag-to-deploy=${{ inputs.image-tag }}" >> $GITHUB_OUTPUT + exit 0 + fi + + REF=$(echo "${{ github.event.ref }}" | sed -n 's#^refs/heads/##p') + if [ "$REF" = "${{ github.event.repository.default_branch }}" ]; then + echo "image-tag-to-deploy=latest" >> $GITHUB_OUTPUT + fi + + PULLS=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://api.github.com/repos/${{ github.repository }}/pulls?head=${{ github.repository_owner }}:${REF}") + PR_NUMBER=$(echo "$PULLS" | jq -r '.[0].number') + + if [ -z "$PR_NUMBER" ]; then + echo "No PR found for branch $REF." + exit 1 + else + echo "PR #$PR_NUMBER found for branch $REF." + echo "image-tag-to-deploy=pr-$PR_NUMBER" >> $GITHUB_OUTPUT + fi + + - name: Check if image exists + run: | + IMAGE_NAME="${{ inputs.main-image-name }}" + IMAGE_TAG="${{ steps.retrieve-image-tag.outputs.image-tag-to-deploy }}" + + ENCODED_TOKEN=$(echo -n "${{ secrets.GITHUB_TOKEN }}" | base64) + TAG_EXISTS=$(curl -s -H "Authorization: Bearer ${ENCODED_TOKEN}" \ + https://ghcr.io/v2/${IMAGE_NAME}/tags/list \ + | jq -r --arg TAG "${IMAGE_TAG}" '.tags[] | select(. == $TAG)') + + if [ -z "$TAG_EXISTS" ]; then + echo "Image ${IMAGE_NAME}:${IMAGE_TAG} does not exist." + exit 1 + else + echo "Image ${IMAGE_NAME}:${IMAGE_TAG} exists." + fi + deploy: + needs: prepare-deploy runs-on: ubuntu-latest environment: name: ${{ inputs.environment }} steps: - - name: Checkout Repository + - name: Checkout repository uses: actions/checkout@v4 - - name: SSH to VM and Execute Docker-Compose Down (if exists) + - name: SSH to VM and execute docker compose down (if exists) uses: appleboy/ssh-action@v1.0.3 with: host: ${{ vars.VM_HOST }} @@ -49,7 +101,7 @@ jobs: # Check if docker-compose.prod.yml exists if [ -f "$COMPOSE_FILE" ]; then echo "$COMPOSE_FILE found." - + # Check if .env exists if [ -f ".env" ]; then docker compose -f "$COMPOSE_FILE" --env-file=".env" down --remove-orphans --rmi all @@ -60,7 +112,7 @@ jobs: echo "$COMPOSE_FILE does not exist. Skipping docker compose down." fi - - name: Copy Docker Compose File to VM Host + - name: Copy docker compose file to VM host uses: appleboy/scp-action@v0.1.7 with: host: ${{ vars.VM_HOST }} @@ -73,7 +125,7 @@ jobs: source: ${{ inputs.docker-compose-file }} target: /home/${{ vars.VM_USERNAME }} - - name: SSH to VM and Create .env File + - name: SSH to VM and create .env file uses: appleboy/ssh-action@v1.0.3 with: host: ${{ vars.VM_HOST }} @@ -87,12 +139,12 @@ jobs: touch .env echo "ENVIRONMENT=${{ inputs.environment }}" > .env - echo "IMAGE_TAG=${{ inputs.image-tag }}" >> .env + echo "IMAGE_TAG=${{ needs.prepare-deploy.outputs.image-tag-to-deploy }}" >> .env if [ "${{ inputs.env-vars }}" != "" ]; then echo "${{ inputs.env-vars }}" >> .env fi - - name: SSH to VM and Execute Docker Compose Up + - name: SSH to VM and execute docker compose up uses: appleboy/ssh-action@v1.0.3 with: host: ${{ vars.VM_HOST }} diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 54ac0cba..90b8ff7b 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: redis: image: redis/redis-stack-server:7.4.0-v1 @@ -22,6 +20,8 @@ services: - APOLLON_REDIS_URL=redis://apollon-redis:6379 - APOLLON_REDIS_DIAGRAM_TTL=${APOLLON_REDIS_DIAGRAM_TTL} - DEPLOYMENT_URL=${DEPLOYMENT_URL} + volumes: + - /opt/apollon/diagrams:/app/diagrams restart: unless-stopped ports: - "8080:8080" diff --git a/docker-compose.yml b/docker-compose.yml index 92b0edc4..6bc6114e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,8 @@ services: - APOLLON_REDIS_URL=redis://apollon_redis:6379 - APOLLON_REDIS_DIAGRAM_TTL=${APOLLON_REDIS_DIAGRAM_TTL} - DEPLOYMENT_URL=${DEPLOYMENT_URL} + volumes: + - ./diagrams:/app/diagrams restart: always networks: - apollon_network