Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68f8000ed8
|
||
|
|
10c11e8f0b | ||
|
|
0a35bc0f77
|
||
|
|
31b2c9da8e | ||
|
|
17bcdd53bf
|
||
|
|
10e0bba9fb | ||
|
|
b93caa1397
|
||
|
|
894aec1ff7 | ||
|
|
93efe09407 | ||
|
|
a88a6788c6 | ||
|
|
ae24edfa2a | ||
|
|
01577a773a | ||
|
|
931e361836 | ||
|
|
db0cdeda91 | ||
|
|
4d9b3e2986 | ||
|
|
bceb9a2e49 |
@@ -6,7 +6,7 @@ on:
|
||||
jobs:
|
||||
build-and-push-app:
|
||||
name: Build & Push App
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: easynode-debian
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
@@ -19,20 +19,19 @@ jobs:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
run: docker buildx inspect --bootstrap
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}/app
|
||||
images: rmcampos/tasknote-app
|
||||
tags: |
|
||||
type=raw,value=candidate
|
||||
|
||||
@@ -51,7 +50,7 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-from: type=registry,ref=rmcampos/tasknote-app:buildcache
|
||||
cache-to: type=registry,ref=rmcampos/tasknote-app:buildcache,mode=max
|
||||
build-args: |
|
||||
VITE_BUILD=${{ steps.version.outputs.tag }}
|
||||
|
||||
@@ -6,7 +6,7 @@ on:
|
||||
jobs:
|
||||
build-and-push-server:
|
||||
name: Build & Push Server
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: graalvm-25
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
@@ -18,42 +18,28 @@ jobs:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- name: Set lowercase repo name
|
||||
id: repo
|
||||
run: echo "name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
- name: Cache Maven dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'server/pom.xml'
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/server/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Log in to GHCR
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_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
|
||||
working-directory: ./server
|
||||
run: |
|
||||
# Use the dynamic repo name to prevent tagging errors
|
||||
./mvnw -Pnative -DskipTests spring-boot:build-image \
|
||||
-Dspring-boot.build-image.imageName=ghcr.io/${{ steps.repo.outputs.name }}/api:latest \
|
||||
-Dspring-boot.build-image.imageName=rmcampos/tasknote-api:latest \
|
||||
-Dspring-boot.build-image.builder=paketobuildpacks/builder-jammy-tiny:latest
|
||||
|
||||
- name: Tag and push candidate
|
||||
run: |
|
||||
docker tag ghcr.io/${{ steps.repo.outputs.name }}/api:latest ghcr.io/${{ steps.repo.outputs.name }}/api:candidate
|
||||
docker push ghcr.io/${{ steps.repo.outputs.name }}/api:candidate
|
||||
docker tag rmcampos/tasknote-api:latest rmcampos/tasknote-api:candidate
|
||||
docker push rmcampos/tasknote-api:candidate
|
||||
|
||||
@@ -20,14 +20,14 @@ on:
|
||||
jobs:
|
||||
terraform-plan:
|
||||
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: easynode-debian
|
||||
outputs:
|
||||
no_changes: ${{ steps.check-changes.outputs.no_changes }}
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -69,10 +69,10 @@ jobs:
|
||||
fi
|
||||
|
||||
if [ -z "$backend_image" ]; then
|
||||
backend_image="ghcr.io/rmcampos/tasknote/api:$latest_backend_tag"
|
||||
backend_image="rmcampos/tasknote-api:$latest_backend_tag"
|
||||
fi
|
||||
if [ -z "$frontend_image" ]; then
|
||||
frontend_image="ghcr.io/rmcampos/tasknote/app:$latest_frontend_tag"
|
||||
frontend_image="rmcampos/tasknote-app:$latest_frontend_tag"
|
||||
fi
|
||||
|
||||
echo "Resolved backend_image=$backend_image"
|
||||
@@ -124,13 +124,13 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Upload plan artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform/tfplan
|
||||
|
||||
terraform-apply:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: easynode-debian
|
||||
needs: terraform-plan
|
||||
if: >
|
||||
(github.event_name == 'push' || github.event_name == 'workflow_run' || inputs.apply == 'true')
|
||||
@@ -142,13 +142,13 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: hashicorp/setup-terraform@v3
|
||||
|
||||
- name: Download plan artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform
|
||||
|
||||
@@ -9,8 +9,8 @@ on:
|
||||
jobs:
|
||||
terraform-plan-stg:
|
||||
name: Plan changs to staging
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: easynode-debian
|
||||
outputs:
|
||||
no_changes: ${{ steps.check-changes.outputs.no_changes }}
|
||||
permissions:
|
||||
@@ -45,8 +45,8 @@ jobs:
|
||||
- name: Determine deployment values
|
||||
id: deploy-vars
|
||||
run: |
|
||||
backend_image="ghcr.io/rmcampos/tasknote/api:candidate"
|
||||
frontend_image="ghcr.io/rmcampos/tasknote/app:candidate"
|
||||
backend_image="rmcampos/tasknote-api:candidate"
|
||||
frontend_image="rmcampos/tasknote-app:candidate"
|
||||
|
||||
echo "backend_image=$backend_image" >> "$GITHUB_OUTPUT"
|
||||
echo "frontend_image=$frontend_image" >> "$GITHUB_OUTPUT"
|
||||
@@ -93,13 +93,13 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Upload plan artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform-stg/tfplan
|
||||
|
||||
terraform-apply:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: easynode-debian
|
||||
needs: terraform-plan-stg
|
||||
if: needs.terraform-plan-stg.outputs.no_changes == 'false'
|
||||
environment:
|
||||
@@ -109,13 +109,13 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: hashicorp/setup-terraform@v3
|
||||
|
||||
- name: Download plan artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: tfplan
|
||||
path: terraform-stg
|
||||
|
||||
@@ -9,75 +9,63 @@ on:
|
||||
- 'server/**/*.java'
|
||||
- 'server/**/*.xml'
|
||||
- 'server/pom.xml'
|
||||
- '.github/workflows/main-server.yml'
|
||||
- '.github/workflows/ci-main-backend.yml'
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: graalvm-25
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Set lowercase repo name
|
||||
id: repo
|
||||
run: echo "name=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
- name: Cache Maven dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/server/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-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 config user.name "gitea-actions[bot]"
|
||||
git config user.email "gitea-actions[bot]@noreply.lightroasted.vps-kinghost.net"
|
||||
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
|
||||
- name: Log in to Docker Hub
|
||||
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
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_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')
|
||||
PR_NUMBER=$(curl -s \
|
||||
-H "Authorization: token ${{ secrets.REGISTRY_TOKEN }}" \
|
||||
"https://lightroasted.vps-kinghost.net/api/v1/repos/${{ github.repository }}/commits/${{ github.sha }}/pull" \
|
||||
| jq -r 'if type == "object" and .number != null then .number | tostring else empty end')
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
echo "No merged PR found for this commit. Falling back to 'candidate' tag."
|
||||
PR_NUMBER="candidate"
|
||||
@@ -88,14 +76,15 @@ jobs:
|
||||
|
||||
- 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 }}
|
||||
docker pull docker.io/rmcampos/tasknote-api:${{ steps.find_pr.outputs.tag }}
|
||||
docker tag docker.io/rmcampos/tasknote-api:${{ steps.find_pr.outputs.tag }} docker.io/rmcampos/tasknote-api:latest
|
||||
docker tag docker.io/rmcampos/tasknote-api:${{ steps.find_pr.outputs.tag }} docker.io/rmcampos/tasknote-api:${{ steps.version.outputs.version }}
|
||||
docker push docker.io/rmcampos/tasknote-api:latest
|
||||
docker push docker.io/rmcampos/tasknote-api:${{ steps.version.outputs.version }}
|
||||
|
||||
- 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 config user.name "gitea-actions[bot]"
|
||||
git config user.email "gitea-actions[bot]@noreply.lightroasted.vps-kinghost.net"
|
||||
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 }}
|
||||
|
||||
@@ -15,26 +15,22 @@ on:
|
||||
- 'client/**/*.js'
|
||||
- 'client/Dockerfile'
|
||||
- 'client/Caddyfile'
|
||||
- '.github/workflows/main-client.yml'
|
||||
- '.github/workflows/ci-main-frontend.yml'
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: easynode-debian
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
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: |
|
||||
@@ -44,21 +40,21 @@ jobs:
|
||||
echo "Generated tag: ${TAG}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
run: docker buildx inspect --bootstrap
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_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')
|
||||
PR_NUMBER=$(curl -s \
|
||||
-H "Authorization: token ${{ secrets.REGISTRY_TOKEN }}" \
|
||||
"https://lightroasted.vps-kinghost.net/api/v1/repos/${{ github.repository }}/commits/${{ github.sha }}/pull" \
|
||||
| jq -r 'if type == "object" and .number != null then .number | tostring else empty end')
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
echo "No merged PR found for this commit. Falling back to 'candidate' tag."
|
||||
PR_NUMBER="candidate"
|
||||
@@ -70,14 +66,13 @@ jobs:
|
||||
- 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 }}
|
||||
--tag rmcampos/tasknote-app:latest \
|
||||
--tag rmcampos/tasknote-app:${{ steps.version.outputs.tag }} \
|
||||
rmcampos/tasknote-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 config user.name "gitea-actions[bot]"
|
||||
git config user.email "gitea-actions[bot]@noreply.lightroasted.vps-kinghost.net"
|
||||
git tag -a ${{ steps.version.outputs.tag }} -m "Release ${{ steps.version.outputs.tag }}"
|
||||
git push origin ${{ steps.version.outputs.tag }}
|
||||
|
||||
|
||||
@@ -11,28 +11,28 @@ on:
|
||||
- 'server/**/*.xml'
|
||||
- 'server/pom.xml'
|
||||
- 'server/**/*.yml'
|
||||
- '.github/workflows/server-ci.yml'
|
||||
- '.github/workflows/ci-pr-backend.yml'
|
||||
|
||||
jobs:
|
||||
run-checks:
|
||||
name: Checks
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: graalvm-25
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
- name: Cache Maven dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'server/pom.xml'
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/server/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Run Check Style
|
||||
working-directory: ./server
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: graalvm-25
|
||||
needs: ["run-checks"]
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -57,74 +57,43 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
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
|
||||
- name: Cache Maven dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '25'
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'server/pom.xml'
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/server/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_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.imageName=rmcampos/tasknote-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 }}
|
||||
docker tag docker.io/rmcampos/tasknote-api:latest docker.io/rmcampos/tasknote-api:candidate
|
||||
docker tag docker.io/rmcampos/tasknote-api:latest docker.io/rmcampos/tasknote-api:pr-${{ github.event.pull_request.number }}
|
||||
docker push docker.io/rmcampos/tasknote-api:candidate
|
||||
docker push docker.io/rmcampos/tasknote-api:pr-${{ github.event.pull_request.number }}
|
||||
|
||||
- name: Create GitHub deployment for staging
|
||||
- name: Create Gitea deployment for staging
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const ref = context.payload.pull_request.head.sha;
|
||||
const env = 'staging';
|
||||
const resp = await github.rest.repos.createDeployment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref,
|
||||
required_contexts: [],
|
||||
environment: env,
|
||||
description: `PR #${context.payload.pull_request.number} preview deployment`,
|
||||
transient_environment: true,
|
||||
auto_merge: false
|
||||
});
|
||||
// create a deployment status pointing to the staging URL
|
||||
await github.rest.repos.createDeploymentStatus({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
deployment_id: resp.data.id,
|
||||
state: 'success',
|
||||
environment_url: 'https://tasknote-stg.darkroasted.vps-kinghost.net'
|
||||
});
|
||||
run: |
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token ${{ secrets.REGISTRY_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://lightroasted.vps-kinghost.net/api/v1/repos/${{ github.repository }}/statuses/${{ github.event.pull_request.head.sha }}" \
|
||||
-d "{\"context\": \"staging/deploy\", \"state\": \"success\", \"description\": \"PR #${{ github.event.pull_request.number }} staging ready\", \"target_url\": \"https://tasknote-stg.darkroasted.vps-kinghost.net\"}"
|
||||
|
||||
@@ -16,26 +16,36 @@ on:
|
||||
- 'client/**/*.js'
|
||||
- 'client/Dockerfile'
|
||||
- 'client/Caddyfile'
|
||||
- '.github/workflows/client-ci.yml'
|
||||
- '.github/workflows/ci-pr-frontend.yml'
|
||||
|
||||
jobs:
|
||||
run-checks:
|
||||
name: Checks
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: easynode-debian
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
- name: Cache npm dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/client/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-npm-
|
||||
|
||||
- name: Debug cache env
|
||||
run: |
|
||||
echo "CACHE_URL=${ACTIONS_CACHE_URL}"
|
||||
echo "RUNTIME_URL=${ACTIONS_RUNTIME_URL}"
|
||||
curl -s -w "\nHTTP: %{http_code}\n" \
|
||||
-H "Authorization: Bearer ${ACTIONS_RUNTIME_TOKEN}" \
|
||||
"${ACTIONS_CACHE_URL}_apis/artifactcache/cache?keys=test&version=test"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
@@ -55,7 +65,7 @@ jobs:
|
||||
|
||||
build-and-push:
|
||||
name: Build & Push
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: easynode-debian
|
||||
needs: ["run-checks"]
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -69,20 +79,19 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
run: docker buildx inspect --bootstrap
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}/app
|
||||
images: rmcampos/tasknote-app
|
||||
tags: |
|
||||
type=raw,value=candidate
|
||||
type=raw,value=pr-${{ github.event.pull_request.number }}
|
||||
@@ -102,33 +111,16 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-from: type=registry,ref=rmcampos/tasknote-app:buildcache
|
||||
cache-to: type=registry,ref=rmcampos/tasknote-app:buildcache,mode=max
|
||||
build-args: |
|
||||
VITE_BUILD=${{ steps.version.outputs.tag }}
|
||||
|
||||
- name: Create GitHub deployment for staging
|
||||
- name: Create Gitea deployment for staging
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const ref = context.payload.pull_request.head.sha;
|
||||
const env = 'staging';
|
||||
const resp = await github.rest.repos.createDeployment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref,
|
||||
required_contexts: [],
|
||||
environment: env,
|
||||
description: `PR #${context.payload.pull_request.number} preview deployment`,
|
||||
transient_environment: true,
|
||||
auto_merge: false
|
||||
});
|
||||
// create a deployment status pointing to the staging URL
|
||||
await github.rest.repos.createDeploymentStatus({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
deployment_id: resp.data.id,
|
||||
state: 'success',
|
||||
environment_url: 'https://tasknote-stg.darkroasted.vps-kinghost.net'
|
||||
});
|
||||
run: |
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token ${{ secrets.REGISTRY_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://lightroasted.vps-kinghost.net/api/v1/repos/${{ github.repository }}/statuses/${{ github.event.pull_request.head.sha }}" \
|
||||
-d "{\"context\": \"staging/deploy\", \"state\": \"success\", \"description\": \"PR #${{ github.event.pull_request.number }} staging ready\", \"target_url\": \"https://tasknote-stg.darkroasted.vps-kinghost.net\"}"
|
||||
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to Tasknote will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## api-v29 && app
|
||||
|
||||
### Changed
|
||||
- Bumped Spring Boot to 4.1.0
|
||||
- CI/CD workflow files updated to run on Gitea.
|
||||
- Container registry switched to Docker Hub.
|
||||
|
||||
## [app-v2026.06.08.22](https://github.com/RMCampos/tasknote/releases/tag/app-v2026.06.08.22) - 2026-06-08
|
||||
|
||||
### Added
|
||||
- Shell Script to confirm new users using docker and sql;
|
||||
|
||||
### Changed
|
||||
- Bumped frontend dependencies to latest versions;
|
||||
- `@types/node` from `25.9.1` to `25.9.2`
|
||||
- `dompurify` from `3.4.7` to `3.4.8`
|
||||
- `i18next` from `26.3.0` to `26.3.1`
|
||||
- `react` from `19.2.6` to `19.2.7`
|
||||
- `react-dom` from `19.2.6` to `19.2.7`
|
||||
- `react-router` from `7.16.0` to `7.17.0`
|
||||
- `@types/react` from `19.2.15` to `19.2.17`
|
||||
- `eslint-plugin-n` from `18.0.1` to `18.1.0`
|
||||
- `typescript-eslint` from `8.60.0` to `8.61.0`
|
||||
- Ngrok and Dev Docker composer files to run using local users id and group id (`UID` and `GID`);
|
||||
|
||||
## [app-v2026.06.08.21](https://github.com/RMCampos/tasknote/releases/tag/app-v2026.06.08.21) - 2026-06-08
|
||||
|
||||
### Changed
|
||||
- The About page to list all current features and tech stack. ([#62](https://github.com/RMCampos/tasknote/issues/62))
|
||||
|
||||
## [app-v2026.06.01.20] - 2026-06-01
|
||||
|
||||
### Changed
|
||||
- Bumped backend and frontend dependencies to latest versions. (#61)
|
||||
|
||||
## [app-v2026.05.26.19] - 2026-05-26
|
||||
|
||||
### Added
|
||||
- SDD and DDD specification files for AI-assisted development, including Spec 001 implementation. (#60)
|
||||
|
||||
## [app-v2026.05.19.18] - 2026-05-19
|
||||
|
||||
### Changed
|
||||
- Auth session refresh now uses server-authoritative current user data instead of stale client state. (#59)
|
||||
|
||||
## [app-v2026.05.18.17] - 2026-05-18
|
||||
|
||||
### Added
|
||||
- Last activity date/time is now tracked and displayed for tasks and notes. (#57)
|
||||
|
||||
## [app-v2026.05.17.16] - 2026-05-17
|
||||
|
||||
### Added
|
||||
- Users must confirm their email address before they can log in. (#56)
|
||||
- Migrated app to new domain with Traefik redirect middleware. (#53)
|
||||
|
||||
### Fixed
|
||||
- Mailgun authentication error (401) when sending emails. (#55)
|
||||
- New domain correctly allowed in CORS and CSP configuration. (#54)
|
||||
|
||||
## [app-v2026.05.13.15] - 2026-05-13
|
||||
|
||||
### Changed
|
||||
- Dropped refresh token logic; auth now relies solely on short-lived access tokens, simplifying the session flow. (#51)
|
||||
|
||||
## [app-v2026.05.13.14] - 2026-05-13
|
||||
|
||||
### Added
|
||||
- Cypress E2E tests covering Home, Task, and Notes management flows. (#46)
|
||||
- Cypress E2E tests for authentication flows. (#39)
|
||||
- Scheduled database backups. (#48)
|
||||
|
||||
### Fixed
|
||||
- Premature route resolution before initial auth check completes. (#45)
|
||||
- Blocked inline styles in CSP via SHA-256 hash in `style-src`. (#43)
|
||||
- Frontend test warnings and errors. (#37)
|
||||
|
||||
### Changed
|
||||
- Upgraded Vite to v8. (#35)
|
||||
|
||||
## [app-v2026.04.29.4] - 2026-04-29
|
||||
|
||||
### Added
|
||||
- Gemini CLI commands and updated AI agent configuration.
|
||||
|
||||
### Changed
|
||||
- Upgraded TypeScript to v6. (#34)
|
||||
|
||||
## [app-v2026.04.29.3] - 2026-04-29
|
||||
|
||||
### Changed
|
||||
- Updated client dependencies to latest minor versions. (#33, #32)
|
||||
|
||||
## [app-v2026.04.16.1] - 2026-04-16
|
||||
|
||||
### Added
|
||||
- Dev environment config files and scripts to run the app locally on VPS. (#29)
|
||||
|
||||
### Security
|
||||
- Improved security posture and added protections against XSS attacks. (#30)
|
||||
|
||||
## [app-v2026.04.08.20] - 2026-04-08
|
||||
|
||||
### Added
|
||||
- GitHub Actions workflow for building server candidate images.
|
||||
|
||||
### Changed
|
||||
- Bumped Spring Boot to 4.0.5. (#27)
|
||||
|
||||
## [app-v2026.04.06.19] - 2026-04-06
|
||||
|
||||
### Added
|
||||
- Kubernetes CD pipeline via GitHub Actions.
|
||||
- Dev container for Java development.
|
||||
- Workflow skips deployment when no source changes detected.
|
||||
|
||||
## [app-v2026.03.17.17] - 2026-03-17
|
||||
|
||||
### Fixed
|
||||
- Missing email templates and configuration for new domain.
|
||||
|
||||
## [app-v2026.03.16.16] - 2026-03-16
|
||||
|
||||
### Fixed
|
||||
- Backend memory leak and state management issues. (#23)
|
||||
- Error messages not propagating back to client in Spring v4.
|
||||
|
||||
### Changed
|
||||
- Updated error messages and translations for improved user feedback.
|
||||
|
||||
## [app-v2026.02.28.15] - 2026-02-28
|
||||
|
||||
### Added
|
||||
- Public note sharing: users can share a note via a public link. (#22)
|
||||
|
||||
## [app-v2026.02.27.13] - 2026-02-27
|
||||
|
||||
### Added
|
||||
- Source and Copy buttons in the note markdown preview modal. (#21)
|
||||
|
||||
### Changed
|
||||
- Upgraded backend to Spring Boot 4.0.3 and Java 25. (#20)
|
||||
|
||||
## [app-v2026.02.05.5] - 2026-02-05
|
||||
|
||||
### Changed
|
||||
- Improved markdown rendering and added home filter context.
|
||||
- Added notes tags support throughout the app. (#13)
|
||||
- Tag suggestion dropdown for Notes and Tasks. (#12)
|
||||
|
||||
### Fixed
|
||||
- Backend null pointer exception.
|
||||
- Filters now persist between actions in the Home view. (#9)
|
||||
|
||||
## [app-v2026.01.18.4] - 2026-01-18
|
||||
|
||||
### Added
|
||||
- CI now uses GHCR (GitHub Container Registry) with unified version tagging for backend images.
|
||||
|
||||
### Changed
|
||||
- Upgraded Spring Boot to 3.5.9.
|
||||
|
||||
### Fixed
|
||||
- Docker image name casing issue causing deployment failures.
|
||||
|
||||
## [app-v2026.01.14.3] - 2026-01-14
|
||||
|
||||
### Changed
|
||||
- Dropped Lombok dependency; bumped to Spring 3.5.9.
|
||||
- Updated backend dependencies to latest versions.
|
||||
|
||||
## [app-v2025.12.15.1] - 2025-12-15
|
||||
|
||||
### Added
|
||||
- Initial release with core task and note management features.
|
||||
- Bruno API collections for local development.
|
||||
|
||||
[app-v2026.06.01.20]: https://github.com/RMCampos/tasknote/compare/app-v2026.05.26.19...app-v2026.06.01.20
|
||||
[app-v2026.05.26.19]: https://github.com/RMCampos/tasknote/compare/app-v2026.05.19.18...app-v2026.05.26.19
|
||||
[app-v2026.05.19.18]: https://github.com/RMCampos/tasknote/compare/app-v2026.05.18.17...app-v2026.05.19.18
|
||||
[app-v2026.05.18.17]: https://github.com/RMCampos/tasknote/compare/app-v2026.05.17.16...app-v2026.05.18.17
|
||||
[app-v2026.05.17.16]: https://github.com/RMCampos/tasknote/compare/app-v2026.05.13.15...app-v2026.05.17.16
|
||||
[app-v2026.05.13.15]: https://github.com/RMCampos/tasknote/compare/app-v2026.05.13.14...app-v2026.05.13.15
|
||||
[app-v2026.05.13.14]: https://github.com/RMCampos/tasknote/compare/app-v2026.04.29.4...app-v2026.05.13.14
|
||||
[app-v2026.04.29.4]: https://github.com/RMCampos/tasknote/compare/app-v2026.04.29.3...app-v2026.04.29.4
|
||||
[app-v2026.04.29.3]: https://github.com/RMCampos/tasknote/compare/app-v2026.04.16.1...app-v2026.04.29.3
|
||||
[app-v2026.04.16.1]: https://github.com/RMCampos/tasknote/compare/app-v2026.04.08.20...app-v2026.04.16.1
|
||||
[app-v2026.04.08.20]: https://github.com/RMCampos/tasknote/compare/app-v2026.04.06.19...app-v2026.04.08.20
|
||||
[app-v2026.04.06.19]: https://github.com/RMCampos/tasknote/compare/app-v2026.03.17.17...app-v2026.04.06.19
|
||||
[app-v2026.03.17.17]: https://github.com/RMCampos/tasknote/compare/app-v2026.03.16.16...app-v2026.03.17.17
|
||||
[app-v2026.03.16.16]: https://github.com/RMCampos/tasknote/compare/app-v2026.02.28.15...app-v2026.03.16.16
|
||||
[app-v2026.02.28.15]: https://github.com/RMCampos/tasknote/compare/app-v2026.02.27.13...app-v2026.02.28.15
|
||||
[app-v2026.02.27.13]: https://github.com/RMCampos/tasknote/compare/app-v2026.02.05.5...app-v2026.02.27.13
|
||||
[app-v2026.02.05.5]: https://github.com/RMCampos/tasknote/compare/app-v2026.01.18.4...app-v2026.02.05.5
|
||||
[app-v2026.01.18.4]: https://github.com/RMCampos/tasknote/compare/app-v2026.01.14.3...app-v2026.01.18.4
|
||||
[app-v2026.01.14.3]: https://github.com/RMCampos/tasknote/compare/app-v2025.12.15.1...app-v2026.01.14.3
|
||||
[app-v2025.12.15.1]: https://github.com/RMCampos/tasknote/releases/tag/app-v2025.12.15.1
|
||||
Generated
+289
-358
File diff suppressed because it is too large
Load Diff
+16
-16
@@ -13,25 +13,25 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@types/node": "^25.7.0",
|
||||
"@types/node": "^25.9.2",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^6.0.1",
|
||||
"@vitejs/plugin-react": "^6.0.2",
|
||||
"bootstrap": "^5.3.8",
|
||||
"dompurify": "^3.4.2",
|
||||
"i18next": "^26.1.0",
|
||||
"react": "^19.2.6",
|
||||
"dompurify": "^3.4.8",
|
||||
"i18next": "^26.3.1",
|
||||
"react": "^19.2.7",
|
||||
"react-bootstrap": "^2.10.10",
|
||||
"react-bootstrap-icons": "^1.11.6",
|
||||
"react-charts": "^3.0.0-beta.57",
|
||||
"react-datepicker": "^9.1.0",
|
||||
"react-dom": "^19.2.6",
|
||||
"react-i18next": "^17.0.7",
|
||||
"react-dom": "^19.2.7",
|
||||
"react-i18next": "^17.0.8",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-router": "^7.15.0",
|
||||
"react-router": "^7.17.0",
|
||||
"react-router-bootstrap": "^0.26.3",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^8.0.12"
|
||||
"vite": "^8.0.16"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "vite --host",
|
||||
@@ -73,23 +73,23 @@
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react": "^19.2.17",
|
||||
"@types/react-router-bootstrap": "^0.26.8",
|
||||
"@vitest/coverage-v8": "^4.1.6",
|
||||
"cypress": "^15.14.2",
|
||||
"@vitest/coverage-v8": "^4.1.8",
|
||||
"cypress": "^15.16.0",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-import-x": "^4.16.2",
|
||||
"eslint-plugin-jsdoc": "^62.9.0",
|
||||
"eslint-plugin-n": "^18.0.1",
|
||||
"eslint-plugin-n": "^18.1.0",
|
||||
"eslint-plugin-promise": "^7.3.0",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"globals": "^17.6.0",
|
||||
"jsdom": "^29.1.1",
|
||||
"prettier": "^3.8.3",
|
||||
"sass": "^1.99.0",
|
||||
"sass": "^1.100.0",
|
||||
"source-map-support": "^0.5.21",
|
||||
"typescript-eslint": "^8.59.3",
|
||||
"vitest": "^4.1.6"
|
||||
"typescript-eslint": "^8.61.0",
|
||||
"vitest": "^4.1.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,5 +25,8 @@ describe('Renders the about view', () => {
|
||||
expect(getByText('Find more information about us and the app')).toBeDefined();
|
||||
expect(getByText('Tasks and notes made')).toBeDefined();
|
||||
expect(getByText('Easy')).toBeDefined();
|
||||
expect(getByText('About TaskNote')).toBeDefined();
|
||||
expect(getByText('Technology')).toBeDefined();
|
||||
expect(getByText('About the Developer')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -132,23 +132,31 @@ const enTranslations = {
|
||||
about_app_features_one: 'Quickly add and manage tasks and notes',
|
||||
about_app_features_two: 'Search and filter notes for easy access',
|
||||
about_app_features_three: 'Intuitive and clean user interface',
|
||||
about_app_features_four: 'Dark and light theme support with responsive design',
|
||||
about_app_features_five: 'URL attachments for tasks and notes',
|
||||
about_app_features_six: 'Tagging system with multiple tags per item',
|
||||
about_app_features_seven: 'Public note sharing via public links',
|
||||
about_app_features_eight: 'Markdown formatting toolbar for rich text editing',
|
||||
about_app_features_nine: 'Email confirmation required for account security',
|
||||
about_app_help_title: 'Help & How to Use',
|
||||
about_app_help_description: `To get started, simply sign up or log in, and
|
||||
you'll have access to your personalized dashboard. From there, you can
|
||||
create, edit, and delete tasks and notes, and organize them however you
|
||||
like. Need assistance? Visit our Help page (in the future) for tutorials
|
||||
and FAQs.`,
|
||||
like. Need assistance? Check out the sidebar for quick navigation.`,
|
||||
|
||||
about_tech_title: 'Technology',
|
||||
about_tech_description: `TaskNote was built using modern web technologies
|
||||
that ensure speed, reliability, and security.`,
|
||||
about_tech_list_one: 'React with TypeScript for the front-end',
|
||||
about_tech_list_two: 'Bootstrap 5 for components and responsive design',
|
||||
about_tech_list_three: 'Java and Spring Boot plus GraalVM for the back-end and Cloud Native',
|
||||
about_tech_list_four: 'PostgreSQL for database management',
|
||||
about_tech_list_five: 'Docker for containerization and deployment',
|
||||
about_tech_list_six: 'GitHub Actions for CI/CD, testing and linting enforcement',
|
||||
about_tech_list_seven: 'SonarCloud, and GitHub QL for security and improvements checks',
|
||||
about_tech_list_one: 'React 19 with TypeScript for the front-end',
|
||||
about_tech_list_two: 'Vite for fast builds and development',
|
||||
about_tech_list_three: 'React Router 7 for client-side routing',
|
||||
about_tech_list_four: 'i18next for internationalization support',
|
||||
about_tech_list_five: 'Bootstrap 5 for components and responsive design',
|
||||
about_tech_list_six: 'Java and Spring Boot 4.x plus GraalVM for the back-end and Cloud Native',
|
||||
about_tech_list_seven: 'PostgreSQL for database management',
|
||||
about_tech_list_eight: 'Docker for containerization and deployment',
|
||||
about_tech_list_nine: 'GitHub Actions for CI/CD, testing and linting enforcement',
|
||||
about_tech_list_ten: 'SonarCloud and GitHub QL for security and improvements checks',
|
||||
|
||||
about_dev_title: 'About the Developer',
|
||||
about_dev_description: `Hi! I'm Ricardo, the developer of TaskNote. I'm
|
||||
|
||||
@@ -133,23 +133,31 @@ const ptBrTranslations = {
|
||||
about_app_features_one: 'Adicionar e gerenciar tarefas e notas rapidamente',
|
||||
about_app_features_two: 'Buscar e filtrar notas para fácil acesso',
|
||||
about_app_features_three: 'Interface limpa e intuitiva',
|
||||
about_app_features_four: 'Suporte a tema escuro e claro com design responsivo',
|
||||
about_app_features_five: 'Anexos de URL para tarefas e notas',
|
||||
about_app_features_six: 'Sistema de tags com múltiplas tags por item',
|
||||
about_app_features_seven: 'Compartilhamento público de notas via links públicos',
|
||||
about_app_features_eight: 'Barra de ferramentas de formatação Markdown para edição de texto rico',
|
||||
about_app_features_nine: 'Confirmação de e-mail obrigatória para segurança da conta',
|
||||
about_app_help_title: 'Ajuda & Como usar',
|
||||
about_app_help_description: `Para começar, simplemente crie sua conta ou entre,
|
||||
e você terá acesso ao seu painel personalizado. A partir daí, você pode criar,
|
||||
alterar, e apagar tarefas e notas, e organizá-las da forma que preferir. Precisa
|
||||
de alguma ajuda? Visite nossa página de ajuda (em breve) para tutoriais e perguntas
|
||||
frequentes.`,
|
||||
de alguma ajuda? Confira a barra lateral para navegação rápida.`,
|
||||
|
||||
about_tech_title: 'Tecnologia',
|
||||
about_tech_description: `TaskNote foi contruído com tecnologia web atual
|
||||
que garante velocidade, confiabilidade e segurança.`,
|
||||
about_tech_list_one: 'React com TypeScript para o desenvolvimento do front-end',
|
||||
about_tech_list_two: 'Bootstrap 5 para os componentes e design responsivo',
|
||||
about_tech_list_three: 'Java e Spring Boot mais GraalVM para o back-end Nativo em Cloud',
|
||||
about_tech_list_four: 'PostgreSQL para gestão do banco de dados',
|
||||
about_tech_list_five: 'Docker para isolamento em containers e lançamentos',
|
||||
about_tech_list_six: 'GitHub Actions para integração contínua, testes e controle de qualidade',
|
||||
about_tech_list_seven: 'SonarCloud e GitHub QL para reforço de qualidade e melhorias',
|
||||
about_tech_list_one: 'React 19 com TypeScript para o desenvolvimento do front-end',
|
||||
about_tech_list_two: 'Vite para builds e desenvolvimento rápidos',
|
||||
about_tech_list_three: 'React Router 7 para roteamento no lado do cliente',
|
||||
about_tech_list_four: 'i18next para suporte à internacionalização',
|
||||
about_tech_list_five: 'Bootstrap 5 para os componentes e design responsivo',
|
||||
about_tech_list_six: 'Java e Spring Boot 4.x mais GraalVM para o back-end Nativo em Cloud',
|
||||
about_tech_list_seven: 'PostgreSQL para gestão do banco de dados',
|
||||
about_tech_list_eight: 'Docker para isolamento em containers e lançamentos',
|
||||
about_tech_list_nine: 'GitHub Actions para integração contínua, testes e controle de qualidade',
|
||||
about_tech_list_ten: 'SonarCloud e GitHub QL para reforço de qualidade e melhorias',
|
||||
|
||||
about_dev_title: 'Sobre o Desenvolvedor',
|
||||
about_dev_description: `Olá! Sou o Ricardo, o desenvolvedor do TaskNote.
|
||||
|
||||
@@ -132,23 +132,31 @@ const ruTranslations = {
|
||||
about_app_features_one: 'Быстро добавляйте и управляйте задачами и заметками',
|
||||
about_app_features_two: 'Поиск и фильтрация заметок для легкого доступа',
|
||||
about_app_features_three: 'Интуитивно понятный пользовательский интерфейс',
|
||||
about_app_features_four: 'Поддержка тёмной и светлой темы с адаптивным дизайном',
|
||||
about_app_features_five: 'URL-вложения для задач и заметок',
|
||||
about_app_features_six: 'Система тегов с несколькими тегами на элемент',
|
||||
about_app_features_seven: 'Публичный доступ к заметкам через публичные ссылки',
|
||||
about_app_features_eight: 'Панель инструментов форматирования Markdown для редактирования',
|
||||
about_app_features_nine: 'Требуется подтверждение электронной почты для безопасности аккаунта',
|
||||
about_app_help_title: 'Помощь и как использовать',
|
||||
about_app_help_description: `Чтобы начать, просто зарегистрируйтесь или войдите в систему, и
|
||||
вы получите доступ к своей персонализированной панели. Оттуда вы можете
|
||||
создавать, редактировать и удалять задачи и заметки, а также организовывать их так, как вам
|
||||
нравится. Нужна помощь? Посетите нашу страницу «Справка» (в будущем) для получения руководств
|
||||
и часто задаваемых вопросов.`,
|
||||
нравится. Нужна помощь? Ознакомьтесь с боковой панелью для быстрой навигации.`,
|
||||
|
||||
about_tech_title: 'Технологии',
|
||||
about_tech_description: `TaskNote был создан с использованием современных веб-технологий,
|
||||
которые обеспечивают скорость, надежность и безопасность.`,
|
||||
about_tech_list_one: 'React с TypeScript для фронтенда',
|
||||
about_tech_list_two: 'Bootstrap 5 для компонентов и адаптивного дизайна',
|
||||
about_tech_list_three: 'Java и Spring Boot плюс GraalVM для бэкенда и Cloud Native',
|
||||
about_tech_list_four: 'PostgreSQL для управления базами данных',
|
||||
about_tech_list_five: 'Docker для контейнеризации и развертывания',
|
||||
about_tech_list_six: 'GitHub Actions для CI/CD, тестирования и принудительного линтинга',
|
||||
about_tech_list_seven: 'SonarCloud и GitHub QL для проверок безопасности и улучшений',
|
||||
about_tech_list_one: 'React 19 с TypeScript для фронтенда',
|
||||
about_tech_list_two: 'Vite для быстрой сборки и разработки',
|
||||
about_tech_list_three: 'React Router 7 для маршрутизации на стороне клиента',
|
||||
about_tech_list_four: 'i18next для поддержки интернационализации',
|
||||
about_tech_list_five: 'Bootstrap 5 для компонентов и адаптивного дизайна',
|
||||
about_tech_list_six: 'Java и Spring Boot 4.x плюс GraalVM для бэкенда и Cloud Native',
|
||||
about_tech_list_seven: 'PostgreSQL для управления базами данных',
|
||||
about_tech_list_eight: 'Docker для контейнеризации и развертывания',
|
||||
about_tech_list_nine: 'GitHub Actions для CI/CD, тестирования и принудительного линтинга',
|
||||
about_tech_list_ten: 'SonarCloud и GitHub QL для проверок безопасности и улучшений',
|
||||
|
||||
about_dev_title: 'О разработчике',
|
||||
about_dev_description: `Привет! Я Рикардо, разработчик TaskNote. Я увлечен созданием приложений,
|
||||
|
||||
@@ -132,23 +132,31 @@ const esTranslations = {
|
||||
about_app_features_one: 'Añade y gestiona tareas y notas de manera rápida',
|
||||
about_app_features_two: 'Busca y filtra notas fácilmente',
|
||||
about_app_features_three: 'Interfaz intuitiva y limpia',
|
||||
about_app_features_four: 'Soporte para tema oscuro y claro con diseño responsivo',
|
||||
about_app_features_five: 'Adjuntos de URL para tareas y notas',
|
||||
about_app_features_six: 'Sistema de etiquetas con múltiples etiquetas por elemento',
|
||||
about_app_features_seven: 'Compartir notas públicamente mediante enlaces públicos',
|
||||
about_app_features_eight: 'Barra de herramientas de formato Markdown para edición de texto enriquecido',
|
||||
about_app_features_nine: 'Confirmación de correo electrónico requerida para la seguridad de la cuenta',
|
||||
about_app_help_title: 'Ayuda & Cómo usar',
|
||||
about_app_help_description: `Para empezar, regístrate o inicia sesión,
|
||||
y tendrás acceso a tu panel personalizado. Desde allí, podrás crear,
|
||||
editar y eliminar tareas y notas, organizándolas como desees. ¿Necesitas
|
||||
ayuda? Visita nuestra página de ayuda (próximamente) para tutoriales y
|
||||
preguntas frecuentes.`,
|
||||
ayuda? Consulta la barra lateral para navegación rápida.`,
|
||||
|
||||
about_tech_title: 'Acerca de la Tecnología',
|
||||
about_tech_description: `TaskNote fue construido con tecnologías web modernas
|
||||
que garantizan velocidad, fiabilidad y seguridad.`,
|
||||
about_tech_list_one: 'React con TypeScript para el desarrollo del frontend',
|
||||
about_tech_list_two: 'Bootstrap 5 para diseño y componentes responsivos',
|
||||
about_tech_list_three: 'Java y Spring Boot más GraalVM para el back-end y Cloud Nativo',
|
||||
about_tech_list_four: 'PostgreSQL para la gestión de bases de datos',
|
||||
about_tech_list_five: 'Docker para la contenedorización y despliegue',
|
||||
about_tech_list_six: 'GitHub Actions para CI/CD, pruebas y control de calidad',
|
||||
about_tech_list_seven: 'SonarCloud y GitHub QL para chequeos de seguridad y mejoras',
|
||||
about_tech_list_one: 'React 19 con TypeScript para el desarrollo del frontend',
|
||||
about_tech_list_two: 'Vite para builds y desarrollo rápidos',
|
||||
about_tech_list_three: 'React Router 7 para enrutamiento del lado del cliente',
|
||||
about_tech_list_four: 'i18next para soporte de internacionalización',
|
||||
about_tech_list_five: 'Bootstrap 5 para diseño y componentes responsivos',
|
||||
about_tech_list_six: 'Java y Spring Boot 4.x más GraalVM para el back-end y Cloud Nativo',
|
||||
about_tech_list_seven: 'PostgreSQL para la gestión de bases de datos',
|
||||
about_tech_list_eight: 'Docker para la contenedorización y despliegue',
|
||||
about_tech_list_nine: 'GitHub Actions para CI/CD, pruebas y control de calidad',
|
||||
about_tech_list_ten: 'SonarCloud y GitHub QL para chequeos de seguridad y mejoras',
|
||||
|
||||
about_dev_title: 'Acerca del Desarrollador',
|
||||
about_dev_description: `¡Hola! Soy Ricardo, el desarrollador de TaskNote.
|
||||
|
||||
@@ -35,6 +35,12 @@ function About(): React.ReactNode {
|
||||
<li>{t('about_app_features_one')}</li>
|
||||
<li>{t('about_app_features_two')}</li>
|
||||
<li>{t('about_app_features_three')}</li>
|
||||
<li>{t('about_app_features_four')}</li>
|
||||
<li>{t('about_app_features_five')}</li>
|
||||
<li>{t('about_app_features_six')}</li>
|
||||
<li>{t('about_app_features_seven')}</li>
|
||||
<li>{t('about_app_features_eight')}</li>
|
||||
<li>{t('about_app_features_nine')}</li>
|
||||
</ul>
|
||||
<h4 className="mt-4 poppins-medium">{t('about_app_help_title')}</h4>
|
||||
<p className="poppins-light">{t('about_app_help_description')}</p>
|
||||
@@ -57,6 +63,9 @@ function About(): React.ReactNode {
|
||||
<li>{t('about_tech_list_five')}</li>
|
||||
<li>{t('about_tech_list_six')}</li>
|
||||
<li>{t('about_tech_list_seven')}</li>
|
||||
<li>{t('about_tech_list_eight')}</li>
|
||||
<li>{t('about_tech_list_nine')}</li>
|
||||
<li>{t('about_tech_list_ten')}</li>
|
||||
</ul>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
@@ -75,7 +84,7 @@ function About(): React.ReactNode {
|
||||
<p className="poppins-light">
|
||||
{t('about_buy_coffee_one')}
|
||||
<a
|
||||
href="https://buy-me-a-coffee-two-nu.vercel.app/"
|
||||
href="https://rmcampos.github.io/buy-me-a-coffee/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
||||
@@ -4,6 +4,7 @@ services:
|
||||
tasknote-web:
|
||||
container_name: tasknote-web
|
||||
image: node:22.14-bookworm-slim
|
||||
user: ${UID:-1000}:${GID:-1000}
|
||||
ports:
|
||||
- "5000:5000"
|
||||
entrypoint: sh -c "npm i --no-update-notifier && npm start"
|
||||
@@ -25,6 +26,7 @@ services:
|
||||
depends_on:
|
||||
tasknote-db:
|
||||
condition: service_started
|
||||
user: ${UID:-1000}:${GID:-1000}
|
||||
environment:
|
||||
POSTGRES_DB: tasknote
|
||||
POSTGRES_HOST: tasknote-db
|
||||
|
||||
@@ -4,6 +4,7 @@ services:
|
||||
tasknote-web:
|
||||
container_name: tasknote-web
|
||||
image: node:22.14-bookworm-slim
|
||||
user: ${UID:-1000}:${GID:-1000}
|
||||
ports:
|
||||
- "5000:5000"
|
||||
entrypoint: sh -c "npm i --no-update-notifier && npm start"
|
||||
@@ -27,6 +28,7 @@ services:
|
||||
depends_on:
|
||||
tasknote-db:
|
||||
condition: service_started
|
||||
user: ${UID:-1000}:${GID:-1000}
|
||||
environment:
|
||||
POSTGRES_DB: tasknote
|
||||
POSTGRES_HOST: tasknote-db
|
||||
|
||||
+13
-7
@@ -5,13 +5,13 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>4.0.6</version>
|
||||
<version>4.0.7</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<groupId>br.com.tasknoteapp</groupId>
|
||||
<artifactId>server</artifactId>
|
||||
<version>28</version>
|
||||
<version>31</version>
|
||||
<name>tasknote-api</name>
|
||||
<description>Java backend REST API to serve TaskNote frontend client</description>
|
||||
|
||||
@@ -49,11 +49,11 @@
|
||||
<jacoco.output.data>${project.build.directory}/coverage-reports</jacoco.output.data>
|
||||
<timestamp>${maven.build.timestamp}</timestamp>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
|
||||
<failsafe.version>3.5.5</failsafe.version>
|
||||
<surefire.version>3.5.5</surefire.version>
|
||||
<jacoco.version>0.8.14</jacoco.version>
|
||||
<failsafe.version>3.5.6</failsafe.version>
|
||||
<surefire.version>3.5.6</surefire.version>
|
||||
<jacoco.version>0.8.15</jacoco.version>
|
||||
<checkstyle.version>3.6.0</checkstyle.version>
|
||||
<springboot.version>4.0.6</springboot.version>
|
||||
<springboot.version>4.0.7</springboot.version>
|
||||
<jjwt.version>0.12.6</jjwt.version>
|
||||
</properties>
|
||||
|
||||
@@ -129,6 +129,12 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-grpc-test</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -364,7 +370,7 @@
|
||||
<version>${springboot.version}</version>
|
||||
<configuration>
|
||||
<image>
|
||||
<name>ghcr.io/rmcampos/tasknote/api:latest</name>
|
||||
<name>docker.io/rmcampos/tasknote-api:latest</name>
|
||||
<buildpacks>
|
||||
<buildpack>file://${project.basedir}/buildpacks/healthcheck</buildpack>
|
||||
<buildpack>urn:cnb:builder:paketo-buildpacks/java-native-image</buildpack>
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
docker run --rm -i --network=host \
|
||||
-e PGPASSWORD=default \
|
||||
postgres:15.8-bookworm \
|
||||
psql -h localhost -U tasknoteuser -d tasknote \
|
||||
-c "UPDATE tasknote.users SET email_confirmed_at = created_at WHERE id > 0;"
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Promote the [Unreleased] section in CHANGELOG.md to a named release.
|
||||
|
||||
Usage:
|
||||
python3 promote-changelog.py <tag> <date> [changelog_path]
|
||||
|
||||
Example:
|
||||
python3 tools/promote-changelog.py app-v2026.06.08.22 2026-06-08
|
||||
python3 tools/promote-changelog.py api-v23 2026-06-08 CHANGELOG.md
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
REPO_URL = "https://github.com/RMCampos/tasknote"
|
||||
|
||||
|
||||
def promote(tag: str, date: str, path: str = "CHANGELOG.md") -> bool:
|
||||
"""
|
||||
Promote [Unreleased] content to a versioned release entry.
|
||||
|
||||
Returns True if the changelog was updated, False if skipped (empty section).
|
||||
Exits with code 1 if the [Unreleased] section cannot be found.
|
||||
"""
|
||||
with open(path, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Match from "## [Unreleased]\n" through the first "\n---\n" separator
|
||||
pattern = r"(## \[Unreleased\]\n)(.*?)(\n---\n)"
|
||||
match = re.search(pattern, content, re.DOTALL)
|
||||
|
||||
if not match:
|
||||
print("ERROR: [Unreleased] section not found in changelog", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
body = match.group(2).strip()
|
||||
|
||||
if not body:
|
||||
print("INFO: [Unreleased] is empty — nothing to promote, skipping")
|
||||
return False
|
||||
|
||||
version_header = f"## [{tag}]({REPO_URL}/releases/tag/{tag}) - {date}"
|
||||
replacement = (
|
||||
f"## [Unreleased]\n\n---\n\n"
|
||||
f"{version_header}\n\n{body}\n\n---\n"
|
||||
)
|
||||
|
||||
new_content = content[: match.start()] + replacement + content[match.end():]
|
||||
|
||||
with open(path, "w") as f:
|
||||
f.write(new_content)
|
||||
|
||||
print(f"SUCCESS: Promoted [Unreleased] to [{tag}]")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: promote-changelog.py <tag> <date> [changelog_path]")
|
||||
sys.exit(1)
|
||||
|
||||
changelog_path = sys.argv[3] if len(sys.argv) > 3 else "CHANGELOG.md"
|
||||
promote(sys.argv[1], sys.argv[2], changelog_path)
|
||||
Reference in New Issue
Block a user