chore: add files and config to run on VPS and test locally (#29)
* chore: add files and config to run on VPS and test locally * chore: add missing nginx files left behind * chore: rename workflow files
This commit is contained in:
@@ -1,107 +0,0 @@
|
||||
name: Frontend PR
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- 'main'
|
||||
paths:
|
||||
- 'client/**/*.html'
|
||||
- 'client/**/*.png'
|
||||
- 'client/**/*.json'
|
||||
- 'client/**/*.txt'
|
||||
- 'client/**/*.ts'
|
||||
- 'client/**/*.tsx'
|
||||
- 'client/**/*.js'
|
||||
- 'client/Dockerfile'
|
||||
- 'client/Caddyfile'
|
||||
- '.github/workflows/client-ci.yml'
|
||||
|
||||
jobs:
|
||||
run-checks:
|
||||
name: Checks
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
working-directory: ./client
|
||||
|
||||
- name: Run lint
|
||||
run: npm run lint
|
||||
working-directory: ./client
|
||||
|
||||
- name: Run build
|
||||
run: npm run build
|
||||
working-directory: ./client
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test:no-watch
|
||||
working-directory: ./client
|
||||
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["run-checks"]
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}/app
|
||||
tags: |
|
||||
type=raw,value=candidate
|
||||
type=raw,value=pr-${{ github.event.pull_request.number }}
|
||||
|
||||
- name: Generate version tag
|
||||
id: version
|
||||
run: |
|
||||
DATE=$(date +'%Y.%m.%d')
|
||||
TAG="app-v${DATE}.${{ github.run_number }}"
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
echo "Generated tag: ${TAG}"
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ./client
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
VITE_BUILD=${{ steps.version.outputs.tag }}
|
||||
@@ -1,136 +0,0 @@
|
||||
name: Deploy to staging
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ "Backend PR", "Frontend PR" ]
|
||||
types: [ completed ]
|
||||
|
||||
jobs:
|
||||
terraform-plan-stg:
|
||||
name: Plan changs to staging
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
no_changes: ${{ steps.check-changes.outputs.no_changes }}
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: hashicorp/setup-terraform@v3
|
||||
|
||||
- name: Setup kubectl
|
||||
uses: azure/setup-kubectl@v4
|
||||
|
||||
- name: Setup Kubeconfig
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBECONFIG_DATA }}" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
- name: Validate cluster access
|
||||
run: |
|
||||
kubectl cluster-info
|
||||
kubectl get namespace tasknote-stg
|
||||
|
||||
- name: Determine deployment values
|
||||
id: deploy-vars
|
||||
run: |
|
||||
backend_image="ghcr.io/rmcampos/tasknote/api:candidate"
|
||||
frontend_image="ghcr.io/rmcampos/tasknote/app:candidate"
|
||||
|
||||
echo "backend_image=$backend_image" >> "$GITHUB_OUTPUT"
|
||||
echo "frontend_image=$frontend_image" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Terraform Fmt -check -diff
|
||||
working-directory: terraform-stg
|
||||
run: terraform fmt -check -diff
|
||||
|
||||
- name: Terraform Init
|
||||
working-directory: terraform-stg
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: terraform init -input=false
|
||||
|
||||
- name: Terraform Validate
|
||||
working-directory: terraform-stg
|
||||
run: terraform validate
|
||||
|
||||
- name: Terraform Plan
|
||||
id: check-changes
|
||||
working-directory: terraform-stg
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: |
|
||||
timeout 1m terraform plan -input=false -out=tfplan \
|
||||
-var="db_user=${{ secrets.DB_USER }}" \
|
||||
-var="db_password=${{ secrets.DB_PASSWORD }}" \
|
||||
-var="db_name=${{ secrets.DB_NAME }}" \
|
||||
-var="security_key=${{ secrets.JWT_SECURITY_KEY }}" \
|
||||
-var="mailgun_apikey=${{ secrets.MAILGUN_API_KEY }}" \
|
||||
-var="backend_image=${{ steps.deploy-vars.outputs.backend_image }}" \
|
||||
-var="frontend_image=${{ steps.deploy-vars.outputs.frontend_image }}" \
|
||||
-var="deploy_version=${{ github.run_id }}"
|
||||
terraform show -json tfplan > tfplan.json
|
||||
if jq -e '.resource_changes | length == 0' tfplan.json >/dev/null; then
|
||||
echo "no_changes=true" >> "$GITHUB_OUTPUT"
|
||||
echo "No changes to apply."
|
||||
exit 0
|
||||
else
|
||||
echo "Changes detected. Proceeding with apply"
|
||||
echo "no_changes=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Upload plan artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform-stg/tfplan
|
||||
|
||||
terraform-apply:
|
||||
runs-on: ubuntu-latest
|
||||
needs: terraform-plan-stg
|
||||
if: needs.terraform-plan-stg.outputs.no_changes == 'false'
|
||||
environment:
|
||||
name: staging
|
||||
url: https://tasknote-stg.darkroasted.vps-kinghost.net
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: hashicorp/setup-terraform@v3
|
||||
|
||||
- name: Download plan artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform-stg
|
||||
|
||||
- name: Setup Kubeconfig
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBECONFIG_DATA }}" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
- name: Terraform Init
|
||||
working-directory: terraform-stg
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: terraform init -input=false
|
||||
|
||||
- name: Terraform Apply
|
||||
working-directory: terraform-stg
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: timeout 1m terraform apply tfplan
|
||||
@@ -1,172 +0,0 @@
|
||||
name: Deploy to prod
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
backend_image:
|
||||
description: "Backend image tag (full image reference)"
|
||||
required: false
|
||||
frontend_image:
|
||||
description: "Frontend image tag (full image reference)"
|
||||
required: false
|
||||
apply:
|
||||
description: "Apply changes after plan"
|
||||
required: false
|
||||
default: "true"
|
||||
workflow_run:
|
||||
workflows: [ "Backend Main", "Frontend Main" ]
|
||||
types: [ completed ]
|
||||
|
||||
jobs:
|
||||
terraform-plan:
|
||||
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
no_changes: ${{ steps.check-changes.outputs.no_changes }}
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: hashicorp/setup-terraform@v3
|
||||
|
||||
- name: Setup kubectl
|
||||
uses: azure/setup-kubectl@v4
|
||||
|
||||
- name: Setup Kubeconfig
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBECONFIG_DATA }}" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
- name: Validate cluster access
|
||||
run: |
|
||||
kubectl cluster-info
|
||||
kubectl get namespace tasknote
|
||||
|
||||
- name: Determine deployment values
|
||||
id: deploy-vars
|
||||
run: |
|
||||
backend_image="${{ github.event.inputs.backend_image }}"
|
||||
frontend_image="${{ github.event.inputs.frontend_image }}"
|
||||
|
||||
latest_backend_tag_tmp="$(git tag --list 'api-v*' | sort -V | tail -n1)"
|
||||
latest_backend_tag="${latest_backend_tag_tmp#api-v}"
|
||||
latest_frontend_tag="$(git tag --list 'app-v*' | sort -V | tail -n1)"
|
||||
|
||||
if [ -z "$latest_backend_tag" ]; then
|
||||
echo "No backend tag found matching [0-9]*" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$latest_frontend_tag" ]; then
|
||||
echo "No frontend tag found matching app-v*" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$backend_image" ]; then
|
||||
backend_image="ghcr.io/rmcampos/tasknote/api:$latest_backend_tag"
|
||||
fi
|
||||
if [ -z "$frontend_image" ]; then
|
||||
frontend_image="ghcr.io/rmcampos/tasknote/app:$latest_frontend_tag"
|
||||
fi
|
||||
|
||||
echo "Resolved backend_image=$backend_image"
|
||||
echo "Resolved frontend_image=$frontend_image"
|
||||
|
||||
echo "backend_image=$backend_image" >> "$GITHUB_OUTPUT"
|
||||
echo "frontend_image=$frontend_image" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Terraform Fmt -check -diff
|
||||
working-directory: terraform
|
||||
run: terraform fmt -check -diff
|
||||
|
||||
- name: Terraform Init
|
||||
working-directory: terraform
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: terraform init -input=false
|
||||
|
||||
- name: Terraform Validate
|
||||
working-directory: terraform
|
||||
run: terraform validate
|
||||
|
||||
- name: Terraform Plan
|
||||
id: check-changes
|
||||
working-directory: terraform
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: |
|
||||
timeout 1m terraform plan -input=false -out=tfplan \
|
||||
-var="db_user=${{ secrets.DB_USER }}" \
|
||||
-var="db_password=${{ secrets.DB_PASSWORD }}" \
|
||||
-var="db_name=${{ secrets.DB_NAME }}" \
|
||||
-var="security_key=${{ secrets.JWT_SECURITY_KEY }}" \
|
||||
-var="mailgun_apikey=${{ secrets.MAILGUN_API_KEY }}" \
|
||||
-var="backend_image=${{ steps.deploy-vars.outputs.backend_image }}" \
|
||||
-var="frontend_image=${{ steps.deploy-vars.outputs.frontend_image }}"
|
||||
terraform show -json tfplan > tfplan.json
|
||||
if jq -e '.resource_changes | length == 0' tfplan.json >/dev/null; then
|
||||
echo "no_changes=true" >> "$GITHUB_OUTPUT"
|
||||
echo "No changes to apply."
|
||||
exit 0
|
||||
else
|
||||
echo "Changes detected. Proceeding with apply"
|
||||
echo "no_changes=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Upload plan artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform/tfplan
|
||||
|
||||
terraform-apply:
|
||||
runs-on: ubuntu-latest
|
||||
needs: terraform-plan
|
||||
if: >
|
||||
(github.event_name == 'push' || github.event_name == 'workflow_run' || inputs.apply == 'true')
|
||||
&& needs.terraform-plan.outputs.no_changes == 'false'
|
||||
environment:
|
||||
name: production
|
||||
url: https://tasknote.darkroasted.vps-kinghost.net
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: hashicorp/setup-terraform@v3
|
||||
|
||||
- name: Download plan artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform
|
||||
|
||||
- name: Setup Kubeconfig
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBECONFIG_DATA }}" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
- name: Terraform Init
|
||||
working-directory: terraform
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: terraform init -input=false
|
||||
|
||||
- name: Terraform Apply
|
||||
working-directory: terraform
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
run: timeout 1m terraform apply tfplan
|
||||
@@ -1,83 +0,0 @@
|
||||
name: Frontend Main
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'client/**/*.html'
|
||||
- 'client/**/*.png'
|
||||
- 'client/**/*.json'
|
||||
- 'client/**/*.txt'
|
||||
- 'client/**/*.ts'
|
||||
- 'client/**/*.tsx'
|
||||
- 'client/**/*.js'
|
||||
- 'client/Dockerfile'
|
||||
- 'client/Caddyfile'
|
||||
- '.github/workflows/main-client.yml'
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set lowercase repo name
|
||||
id: repo
|
||||
run: echo "name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version tag
|
||||
id: version
|
||||
run: |
|
||||
DATE=$(date +'%Y.%m.%d')
|
||||
TAG="app-v${DATE}.${{ github.run_number }}"
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
echo "Generated tag: ${TAG}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Find PR number
|
||||
id: find_pr
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
PR_NUMBER=$(gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number')
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
echo "No merged PR found for this commit. Falling back to 'candidate' tag."
|
||||
PR_NUMBER="candidate"
|
||||
else
|
||||
PR_NUMBER="pr-${PR_NUMBER}"
|
||||
fi
|
||||
echo "tag=${PR_NUMBER}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Promote Docker image
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
--tag ghcr.io/${{ steps.repo.outputs.name }}/app:latest \
|
||||
--tag ghcr.io/${{ steps.repo.outputs.name }}/app:${{ steps.version.outputs.tag }} \
|
||||
ghcr.io/${{ steps.repo.outputs.name }}/app:${{ steps.find_pr.outputs.tag }}
|
||||
|
||||
- name: Create and push Git tag
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git tag -a ${{ steps.version.outputs.tag }} -m "Release ${{ steps.version.outputs.tag }}"
|
||||
git push origin ${{ steps.version.outputs.tag }}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
name: Backend Main
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'server/**/*.java'
|
||||
- 'server/**/*.xml'
|
||||
- 'server/pom.xml'
|
||||
- '.github/workflows/main-server.yml'
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set lowercase repo name
|
||||
id: repo
|
||||
run: echo "name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
|
||||
- name: Increment version in pom.xml
|
||||
id: version
|
||||
working-directory: ./server
|
||||
run: |
|
||||
# Extract current version from pom.xml
|
||||
CURRENT_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
|
||||
echo "Current version: ${CURRENT_VERSION}"
|
||||
|
||||
# Increment version
|
||||
NEW_VERSION=$((CURRENT_VERSION + 1))
|
||||
echo "New version: ${NEW_VERSION}"
|
||||
|
||||
# Update pom.xml with new version
|
||||
./mvnw versions:set -DnewVersion=${NEW_VERSION} -DgenerateBackupFiles=false -q
|
||||
|
||||
# Output for later steps
|
||||
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Commit version bump
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add server/pom.xml
|
||||
git commit -m "chore: bump api version to ${{ steps.version.outputs.version }} [skip ci]"
|
||||
git push
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Find PR number
|
||||
id: find_pr
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
PR_NUMBER=$(gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number')
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
echo "No merged PR found for this commit. Falling back to 'candidate' tag."
|
||||
PR_NUMBER="candidate"
|
||||
else
|
||||
PR_NUMBER="pr-${PR_NUMBER}"
|
||||
fi
|
||||
echo "tag=${PR_NUMBER}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Promote Docker image
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
--tag ghcr.io/${{ steps.repo.outputs.name }}/api:latest \
|
||||
--tag ghcr.io/${{ steps.repo.outputs.name }}/api:${{ steps.version.outputs.version }} \
|
||||
ghcr.io/${{ steps.repo.outputs.name }}/api:${{ steps.find_pr.outputs.tag }}
|
||||
|
||||
- name: Create and push Git tag
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git tag -a api-v${{ steps.version.outputs.version }} -m "Release API v${{ steps.version.outputs.version }}"
|
||||
git push origin api-v${{ steps.version.outputs.version }}
|
||||
@@ -1,102 +0,0 @@
|
||||
name: Backend PR
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- 'main'
|
||||
paths:
|
||||
- 'server/**/*.java'
|
||||
- 'server/**/*.xml'
|
||||
- 'server/pom.xml'
|
||||
- '.github/workflows/server-ci.yml'
|
||||
|
||||
jobs:
|
||||
run-checks:
|
||||
name: Checks
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'server/pom.xml'
|
||||
|
||||
- name: Run Check Style
|
||||
working-directory: ./server
|
||||
run: ./mvnw --no-transfer-progress checkstyle:check -Dcheckstyle.skip=false
|
||||
|
||||
- name: Run build
|
||||
working-directory: ./server
|
||||
run: ./mvnw --no-transfer-progress clean compile -DskipTests
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ./server
|
||||
run: ./mvnw --no-transfer-progress clean verify -P tests --file pom.xml
|
||||
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["run-checks"]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set lowercase repo name
|
||||
id: repo
|
||||
run: echo "name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'server/pom.xml'
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Cache Buildpack layers
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/reproducible-builds
|
||||
key: ${{ runner.os }}-buildpack-${{ hashFiles('server/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildpack-
|
||||
|
||||
- name: Build Docker image with Spring Boot
|
||||
working-directory: ./server
|
||||
run: |
|
||||
./mvnw -Pnative -DskipTests spring-boot:build-image \
|
||||
-Dspring-boot.build-image.imageName=ghcr.io/${{ steps.repo.outputs.name }}/api:latest \
|
||||
-Dspring-boot.build-image.builder=paketobuildpacks/builder-jammy-tiny:latest
|
||||
|
||||
- name: Tag and push Docker image
|
||||
run: |
|
||||
docker tag ghcr.io/${{ steps.repo.outputs.name }}/api:latest ghcr.io/${{ steps.repo.outputs.name }}/api:candidate
|
||||
docker tag ghcr.io/${{ steps.repo.outputs.name }}/api:latest ghcr.io/${{ steps.repo.outputs.name }}/api:pr-${{ github.event.pull_request.number }}
|
||||
docker push ghcr.io/${{ steps.repo.outputs.name }}/api:candidate
|
||||
docker push ghcr.io/${{ steps.repo.outputs.name }}/api:pr-${{ github.event.pull_request.number }}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { env } from '../env';
|
||||
|
||||
const server = env.VITE_BACKEND_SERVER;
|
||||
const server = env.VITE_BACKEND_SERVER || '/api';
|
||||
|
||||
const ApiConfig = {
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ services:
|
||||
context: ./client
|
||||
dockerfile: Dockerfile
|
||||
ports: ["5000:5000"]
|
||||
environment:
|
||||
VITE_BACKEND_SERVER: http://localhost:8585
|
||||
networks:
|
||||
- tasknote-network
|
||||
|
||||
@@ -27,7 +25,7 @@ services:
|
||||
POSTGRES_USER: tasknoteuser
|
||||
POSTGRES_PASSWORD: default
|
||||
POSTGRES_PORT: 5432
|
||||
CORS_ALLOWED_ORIGINS: http://tasknote-web:5000, http://localhost:5000
|
||||
CORS_ALLOWED_ORIGINS: http://tasknote-web:5000, http://localhost:5000, https://flattop-depth-dropper.ngrok-free.dev
|
||||
SERVER_SERVLET_CONTEXT_PATH: /
|
||||
TARGET_ENV: development
|
||||
SECURITY_KEY: this-is-a-very-long-security-key-for-dev
|
||||
@@ -62,4 +60,4 @@ services:
|
||||
|
||||
networks:
|
||||
tasknote-network:
|
||||
driver: bridge
|
||||
external: true
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
events {}
|
||||
http {
|
||||
server {
|
||||
listen 8181;
|
||||
server_name _;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://tasknote-api:8585/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://tasknote-web:5000/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
ngrok http 8181 --log=stdout > ngrok-8181.log 2>&1 &
|
||||
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
docker run -d \
|
||||
--name ngrok-tasknote-proxy \
|
||||
-p 127.0.0.1:8181:8181 \
|
||||
-v ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
|
||||
--restart unless-stopped \
|
||||
--network tasknote-network \
|
||||
nginx:stable
|
||||
Reference in New Issue
Block a user