From a85225612e5acf0afcef89b637323ef644082158 Mon Sep 17 00:00:00 2001 From: Matt DiMeglio Date: Sat, 14 Jun 2025 12:13:54 -0400 Subject: [PATCH 1/3] Add API and add Web specific webhook secrets --- .github/workflows/api-container.yml | 95 ++++++++++++++++++++++++ .github/workflows/api-deploy-nonprod.yml | 94 +++++++++++++++++++++++ .github/workflows/api-deploy-prod.yml | 94 +++++++++++++++++++++++ .github/workflows/web-container.yml | 4 +- .github/workflows/web-deploy-nonprod.yml | 10 +-- .github/workflows/web-deploy-prod.yml | 10 +-- 6 files changed, 295 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/api-container.yml create mode 100644 .github/workflows/api-deploy-nonprod.yml create mode 100644 .github/workflows/api-deploy-prod.yml diff --git a/.github/workflows/api-container.yml b/.github/workflows/api-container.yml new file mode 100644 index 0000000..37244b7 --- /dev/null +++ b/.github/workflows/api-container.yml @@ -0,0 +1,95 @@ +name: API Deployment Container +on: + workflow_dispatch: {} + pull_request: + branches: + - main + types: + - opened + - reopened + - synchronize + - ready_for_review + push: + branches: + - main + paths: + - api/** +jobs: + determine-workflow: + runs-on: 'ubuntu-latest' + outputs: + workflow_type: ${{ steps.workflow.outputs.workflow_type }} + workflow_envs: ${{ steps.workflow.outputs.workflow_envs }} + release_type: ${{ steps.workflow.outputs.release_type }} + current_version: ${{ steps.version.outputs.current_version }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + - name: Determine Workflow + id: workflow + shell: bash + run: | + event=${{ github.event_name }} + workflow_type='dev'; + workflow_envs='["dev"]' + if [[ $event == 'workflow_dispatch' && '${{ github.ref_name }}' == 'main' ]]; + then + echo "in if statement" + workflow_type='release'; + workflow_envs='["prod"]' + fi + + echo "workflow_type=$workflow_type" >> $GITHUB_OUTPUT + echo "workflow_envs=$workflow_envs" >> $GITHUB_OUTPUT + + echo "Running $workflow_type pipeline in environments: $workflow_envs" >> $GITHUB_STEP_SUMMARY + - name: Extract Version + id: version + shell: bash + run: | + version=$(jq -r '.version' api/package.json) + echo "current_version=$version" >> "$GITHUB_OUTPUT" + nonprod-deploy: + needs: determine-workflow + if: needs.determine-workflow.outputs.workflow_type != 'release' + strategy: + max-parallel: 1 + matrix: + env: ${{ fromJson(needs.determine-workflow.outputs.workflow_envs) }} + uses: ./.github/workflows/api-deploy-nonprod.yml + with: + environments: ${{ matrix.env }} + workflow_type: ${{ needs.determine-workflow.outputs.workflow_type }} + branch: ${{ github.head_ref || github.ref_name }} + current_version: ${{ needs.determine-workflow.outputs.current_version }} + secrets: + DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + TEST: ${{ secrets.TEST }} + COOLIFY_WEBHOOK_API: ${{ secrets.COOLIFY_WEBHOOK_API }} + COOLIFY_TOKEN: ${{ secrets.COOLIFY_TOKEN }} + permissions: + contents: read + packages: write + prod-deploy: + needs: determine-workflow + if: needs.determine-workflow.outputs.workflow_type == 'release' + strategy: + max-parallel: 1 + matrix: + env: ${{ fromJson(needs.determine-workflow.outputs.workflow_envs) }} + uses: ./.github/workflows/api-deploy-prod.yml + with: + environments: ${{ matrix.env }} + workflow_type: ${{ needs.determine-workflow.outputs.workflow_type }} + branch: ${{ github.head_ref || github.ref_name }} + current_version: ${{ needs.determine-workflow.outputs.current_version }} + secrets: + DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + TEST: ${{ secrets.TEST }} + COOLIFY_WEBHOOK_API: ${{ secrets.COOLIFY_WEBHOOK_API }} + COOLIFY_TOKEN: ${{ secrets.COOLIFY_TOKEN }} + permissions: + contents: read + packages: write diff --git a/.github/workflows/api-deploy-nonprod.yml b/.github/workflows/api-deploy-nonprod.yml new file mode 100644 index 0000000..ff3547c --- /dev/null +++ b/.github/workflows/api-deploy-nonprod.yml @@ -0,0 +1,94 @@ +name: API Deployment Non-Production +on: + workflow_call: + inputs: + environments: + type: string + description: An optional list of environments to deploy to. + default: 'dev' + workflow_type: + type: string + description: An optional string for workflow types. + default: 'dev' + branch: + type: string + description: An optional string to define which branch to checkout. + default: 'main' + current_version: + type: string + description: Current Version of the package.json. + default: '0.0.0' + secrets: + DOCKERHUB_USER: {} + DOCKERHUB_TOKEN: {} + TEST: {} + COOLIFY_WEBHOOK_API: {} + COOLIFY_TOKEN: {} +jobs: + check-inputs: + runs-on: 'ubuntu-latest' + environment: ${{ inputs.environments }} + steps: + - name: Check secrets present + run: | + if [[ -z "${{ secrets.COOLIFY_WEBHOOK_API }}" ]]; then + echo "COOLIFY_WEBHOOK_API secret is empty or missing" + exit 1 + else + echo "COOLIFY_WEBHOOK_API secret is set" + fi + if [[ -z "${{ secrets.COOLIFY_TOKEN }}" ]]; then + echo "COOLIFY_TOKEN secret is empty or missing" + exit 1 + else + echo "COOLIFY_TOKEN secret is set" + fi + if [[ -z "${{ secrets.DOCKERHUB_USER }}" ]]; then + echo "DOCKERHUB_USER secret is empty or missing" + exit 1 + else + echo "DOCKERHUB_USER secret is set" + fi + if [[ -z "${{ secrets.DOCKERHUB_TOKEN }}" ]]; then + echo "DOCKERHUB_TOKEN secret is empty or missing" + exit 1 + else + echo "DOCKERHUB_TOKEN secret is set" + fi + echo "Current Version: ${{inputs.current_version}}" + build: + needs: check-inputs + if: needs.check-inputs.result == 'success' && inputs.workflow_type != 'release' + environment: ${{ inputs.environments }} + runs-on: 'ubuntu-latest' + permissions: + contents: read + packages: write + steps: + - name: Branch Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + - name: Login to Docker + uses: docker/login-action@v3 + with: + registry: docker.io + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Docker Build Backend + run: docker build -f api/Dockerfile -t john4064/shiftsync:latest_api ./api --build-arg ENVIRONMENT=dev + - name: Docker Push Backend + run: docker push john4064/shiftsync:latest_api + deploy: + needs: build + if: needs.build.result == 'success' && inputs.workflow_type != 'release' + environment: ${{ inputs.environments }} + runs-on: 'ubuntu-latest' + permissions: + contents: read + packages: write + steps: + - name: Deploy to Coolify + run: | + curl --request GET '${{ secrets.COOLIFY_WEBHOOK_API }}' --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}' + diff --git a/.github/workflows/api-deploy-prod.yml b/.github/workflows/api-deploy-prod.yml new file mode 100644 index 0000000..63ff524 --- /dev/null +++ b/.github/workflows/api-deploy-prod.yml @@ -0,0 +1,94 @@ +name: API Deployment Production +on: + workflow_call: + inputs: + environments: + type: string + description: An optional list of environments to deploy to. + default: 'prod' + workflow_type: + type: string + description: An optional string for workflow types. + default: 'prod' + branch: + type: string + description: An optional string to define which branch to checkout. + default: 'main' + current_version: + type: string + description: Current Version of the package.json. + default: '0.0.0' + secrets: + DOCKERHUB_USER: {} + DOCKERHUB_TOKEN: {} + TEST: {} + COOLIFY_WEBHOOK_API: {} + COOLIFY_TOKEN: {} +jobs: + check-inputs: + runs-on: 'ubuntu-latest' + environment: ${{ inputs.environments }} + steps: + - name: Check secrets present + run: | + if [[ -z "${{ secrets.COOLIFY_WEBHOOK_API }}" ]]; then + echo "COOLIFY_WEBHOOK_API secret is empty or missing" + exit 1 + else + echo "COOLIFY_WEBHOOK_API secret is set" + fi + if [[ -z "${{ secrets.COOLIFY_TOKEN }}" ]]; then + echo "COOLIFY_TOKEN secret is empty or missing" + exit 1 + else + echo "COOLIFY_TOKEN secret is set" + fi + if [[ -z "${{ secrets.DOCKERHUB_USER }}" ]]; then + echo "DOCKERHUB_USER secret is empty or missing" + exit 1 + else + echo "DOCKERHUB_USER secret is set" + fi + if [[ -z "${{ secrets.DOCKERHUB_TOKEN }}" ]]; then + echo "DOCKERHUB_TOKEN secret is empty or missing" + exit 1 + else + echo "DOCKERHUB_TOKEN secret is set" + fi + echo "Current Version: ${{inputs.current_version}}" + build: + needs: check-inputs + if: needs.check-inputs.result == 'success' && inputs.workflow_type == 'release' + environment: ${{ inputs.environments }} + runs-on: 'ubuntu-latest' + permissions: + contents: read + packages: write + steps: + - name: Branch Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + - name: Login to Docker + uses: docker/login-action@v3 + with: + registry: docker.io + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Docker Build Backend + run: docker build -f api/Dockerfile -t john4064/shiftsync:prod_api ./api --build-arg ENVIRONMENT=prod + - name: Docker Push Backend + run: docker push john4064/shiftsync:prod_api + deploy: + needs: build + if: needs.build.result == 'success' && inputs.workflow_type == 'release' + environment: ${{ inputs.environments }} + runs-on: 'ubuntu-latest' + permissions: + contents: read + packages: write + steps: + - name: Deploy to Coolify + run: | + curl --request GET '${{ secrets.COOLIFY_WEBHOOK_API }}' --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}' + diff --git a/.github/workflows/web-container.yml b/.github/workflows/web-container.yml index 095eeec..61aeca7 100644 --- a/.github/workflows/web-container.yml +++ b/.github/workflows/web-container.yml @@ -66,7 +66,7 @@ jobs: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} TEST: ${{ secrets.TEST }} - COOLIFY_WEBHOOK: ${{ secrets.COOLIFY_WEBHOOK }} + COOLIFY_WEBHOOK_WEB: ${{ secrets.COOLIFY_WEBHOOK_WEB }} COOLIFY_TOKEN: ${{ secrets.COOLIFY_TOKEN }} permissions: contents: read @@ -88,7 +88,7 @@ jobs: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} TEST: ${{ secrets.TEST }} - COOLIFY_WEBHOOK: ${{ secrets.COOLIFY_WEBHOOK }} + COOLIFY_WEBHOOK_WEB: ${{ secrets.COOLIFY_WEBHOOK_WEB }} COOLIFY_TOKEN: ${{ secrets.COOLIFY_TOKEN }} permissions: contents: read diff --git a/.github/workflows/web-deploy-nonprod.yml b/.github/workflows/web-deploy-nonprod.yml index f1669a3..61fcb6b 100644 --- a/.github/workflows/web-deploy-nonprod.yml +++ b/.github/workflows/web-deploy-nonprod.yml @@ -22,7 +22,7 @@ on: DOCKERHUB_USER: {} DOCKERHUB_TOKEN: {} TEST: {} - COOLIFY_WEBHOOK: {} + COOLIFY_WEBHOOK_WEB: {} COOLIFY_TOKEN: {} jobs: check-inputs: @@ -31,11 +31,11 @@ jobs: steps: - name: Check secrets present run: | - if [[ -z "${{ secrets.COOLIFY_WEBHOOK }}" ]]; then - echo "COOLIFY_WEBHOOK secret is empty or missing" + if [[ -z "${{ secrets.COOLIFY_WEBHOOK_WEB }}" ]]; then + echo "COOLIFY_WEBHOOK_WEB secret is empty or missing" exit 1 else - echo "COOLIFY_WEBHOOK secret is set" + echo "COOLIFY_WEBHOOK_WEB secret is set" fi if [[ -z "${{ secrets.COOLIFY_TOKEN }}" ]]; then echo "COOLIFY_TOKEN secret is empty or missing" @@ -90,5 +90,5 @@ jobs: steps: - name: Deploy to Coolify run: | - curl --request GET '${{ secrets.COOLIFY_WEBHOOK }}' --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}' + curl --request GET '${{ secrets.COOLIFY_WEBHOOK_WEB }}' --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}' diff --git a/.github/workflows/web-deploy-prod.yml b/.github/workflows/web-deploy-prod.yml index c7d2e49..6c87dcc 100644 --- a/.github/workflows/web-deploy-prod.yml +++ b/.github/workflows/web-deploy-prod.yml @@ -22,7 +22,7 @@ on: DOCKERHUB_USER: {} DOCKERHUB_TOKEN: {} TEST: {} - COOLIFY_WEBHOOK: {} + COOLIFY_WEBHOOK_WEB: {} COOLIFY_TOKEN: {} jobs: check-inputs: @@ -31,11 +31,11 @@ jobs: steps: - name: Check secrets present run: | - if [[ -z "${{ secrets.COOLIFY_WEBHOOK }}" ]]; then - echo "COOLIFY_WEBHOOK secret is empty or missing" + if [[ -z "${{ secrets.COOLIFY_WEBHOOK_WEB }}" ]]; then + echo "COOLIFY_WEBHOOK_WEB secret is empty or missing" exit 1 else - echo "COOLIFY_WEBHOOK secret is set" + echo "COOLIFY_WEBHOOK_WEB secret is set" fi if [[ -z "${{ secrets.COOLIFY_TOKEN }}" ]]; then echo "COOLIFY_TOKEN secret is empty or missing" @@ -90,5 +90,5 @@ jobs: steps: - name: Deploy to Coolify run: | - curl --request GET '${{ secrets.COOLIFY_WEBHOOK }}' --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}' + curl --request GET '${{ secrets.COOLIFY_WEBHOOK_WEB }}' --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}' From 0f0c9b7902b9437502d48d99c1f3bd0af0099ec9 Mon Sep 17 00:00:00 2001 From: Matt DiMeglio Date: Sat, 14 Jun 2025 12:31:00 -0400 Subject: [PATCH 2/3] Add Dockerfiles --- api/.dockerignore | 1 + api/Dockerfile | 17 +++++++++++++++++ api/docker-compose.yaml | 14 ++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 api/.dockerignore create mode 100644 api/Dockerfile create mode 100644 api/docker-compose.yaml diff --git a/api/.dockerignore b/api/.dockerignore new file mode 100644 index 0000000..0979a6c --- /dev/null +++ b/api/.dockerignore @@ -0,0 +1 @@ +**/node_modules/** diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 0000000..b5a4b73 --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,17 @@ +FROM node:20-alpine + +WORKDIR /app + +COPY ./package*.json ./ + +RUN npm ci + +COPY . ./ + +EXPOSE 5172 +EXPOSE 5170 + +ARG ENVIRONMENT +ENV ENVIRONMENT ${ENVIRONMENT} + +CMD npm run ${ENVIRONMENT} diff --git a/api/docker-compose.yaml b/api/docker-compose.yaml new file mode 100644 index 0000000..347119c --- /dev/null +++ b/api/docker-compose.yaml @@ -0,0 +1,14 @@ +services: + shiftsync-web: + image: 'docker.io/john4064/shiftsync:prod_api' + environment: + - 'TESTVAR=${COOLIFY_VAR}' + volumes: + - /home/jparkhurst/shiftsync:/shiftsync + ports: + - "5172:5172" + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:5172"] + interval: 10s + timeout: 5s + retries: 5 \ No newline at end of file From 4b50535b2ab20a3c8db51639726bc1d8f89ff038 Mon Sep 17 00:00:00 2001 From: Matt DiMeglio Date: Sat, 14 Jun 2025 12:35:25 -0400 Subject: [PATCH 3/3] add api/web --- .github/workflows/api-container.yml | 4 ++-- .github/workflows/web-container.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/api-container.yml b/.github/workflows/api-container.yml index 37244b7..e4df4b0 100644 --- a/.github/workflows/api-container.yml +++ b/.github/workflows/api-container.yml @@ -49,7 +49,7 @@ jobs: run: | version=$(jq -r '.version' api/package.json) echo "current_version=$version" >> "$GITHUB_OUTPUT" - nonprod-deploy: + nonprod-deploy-api: needs: determine-workflow if: needs.determine-workflow.outputs.workflow_type != 'release' strategy: @@ -71,7 +71,7 @@ jobs: permissions: contents: read packages: write - prod-deploy: + prod-deploy-api: needs: determine-workflow if: needs.determine-workflow.outputs.workflow_type == 'release' strategy: diff --git a/.github/workflows/web-container.yml b/.github/workflows/web-container.yml index 61aeca7..fe29787 100644 --- a/.github/workflows/web-container.yml +++ b/.github/workflows/web-container.yml @@ -49,7 +49,7 @@ jobs: run: | version=$(jq -r '.version' web/package.json) echo "current_version=$version" >> "$GITHUB_OUTPUT" - nonprod-deploy: + nonprod-deploy-web: needs: determine-workflow if: needs.determine-workflow.outputs.workflow_type != 'release' strategy: @@ -71,7 +71,7 @@ jobs: permissions: contents: read packages: write - prod-deploy: + prod-deploy-web: needs: determine-workflow if: needs.determine-workflow.outputs.workflow_type == 'release' strategy: