Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/auto-merge-on-approval.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Auto-merge on approval
on:
pull_request_review:
types: [submitted]

jobs:
automerge:
if: ${{ github.event.review.state == 'approved' }}
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: write
checks: read
steps:
- name: Attempt merge when approved
run: |
echo "Auto-merge on approval disabled."
echo "Please merge the PR manually after required checks and approvals pass."
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

jobs:
build:
name: Build and Test
runs-on: ubuntu-latest

steps:
Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Deploy to Azure (on merge to main)

on:
push:
branches: [main]

env:
DOTNET_VERSION: "9.0.x"

jobs:
build-and-deploy:
name: Build, Publish and Deploy
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Restore
run: dotnet restore Aquiis.sln

- name: Publish
run: dotnet publish ./Aquiis.SimpleStart/Aquiis.SimpleStart.csproj -c Release -o ./publish

- name: Azure Login (for deployment)
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Deploy with Azure CLI
run: |
az webapp deploy \
--resource-group ${{ secrets.AZURE_RESOURCE_GROUP }} \
--name ${{ secrets.AZURE_WEBAPP_NAME }} \
--src-path ./publish

- name: Save publish profile to file
run: |
echo "${{ secrets.AZURE_PUBLISH_PROFILE }}" > /tmp/publish_profile.xml

- name: Extract DB settings and export to GITHUB_ENV
run: |
DB_FILE=$(jq -r '.ApplicationSettings.DatabaseFileName // "app_v0.0.0.db"' Aquiis.SimpleStart/appsettings.json)
PREV_DB_FILE=$(jq -r '.ApplicationSettings.PreviousDatabaseFileName // ""' Aquiis.SimpleStart/appsettings.json)
APP_VERSION=$(jq -r '.ApplicationSettings.Version // ""' Aquiis.SimpleStart/appsettings.json)
SCHEMA_VERSION=$(jq -r '.ApplicationSettings.SchemaVersion // ""' Aquiis.SimpleStart/appsettings.json)
echo "DB_FILE=$DB_FILE" >> "$GITHUB_ENV"
echo "PREV_DB_FILE=$PREV_DB_FILE" >> "$GITHUB_ENV"
echo "APP_VERSION=$APP_VERSION" >> "$GITHUB_ENV"
echo "SCHEMA_VERSION=$SCHEMA_VERSION" >> "$GITHUB_ENV"
echo "DB_PATH=/home/data/$DB_FILE" >> "$GITHUB_ENV"
shell: bash

- name: Create /home/data on App Service
run: |
chmod +x ./scripts/kudu-create-data-dir.sh
./scripts/kudu-create-data-dir.sh /tmp/publish_profile.xml ${{ secrets.AZURE_WEBAPP_NAME }}

- name: Backup existing DB (if any)
run: |
chmod +x ./scripts/kudu-backup-db.sh
./scripts/kudu-backup-db.sh /tmp/publish_profile.xml ${{ secrets.AZURE_WEBAPP_NAME }} "$DB_PATH" || true

- name: Azure Login (for App Settings)
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Configure App Settings (set SQLite connection string and app metadata)
run: |
az webapp config appsettings set \
--resource-group "${{ secrets.AZURE_RESOURCE_GROUP }}" \
--name "${{ secrets.AZURE_WEBAPP_NAME }}" \
--settings \
"ConnectionStrings__DefaultConnection=DataSource=/home/data/$DB_FILE;Cache=Shared" \
"ApplicationSettings__Version=$APP_VERSION" \
"ApplicationSettings__DatabaseFileName=$DB_FILE" \
"ApplicationSettings__PreviousDatabaseFileName=$PREV_DB_FILE" \
"ApplicationSettings__SchemaVersion=$SCHEMA_VERSION" \
ASPNETCORE_ENVIRONMENT=Production
shell: bash
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Data/Backups/**

/Data/app*

sp_credentials.json

publish_profile.xml


# Python virtual environment created per-project
.venv/
Expand Down
25 changes: 25 additions & 0 deletions scripts/kudu-backup-db.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euo pipefail
# Usage: ./kudu-backup-db.sh /path/to/publish_profile.xml APP_NAME [/home/data/app.db]
PUBLISH_PROFILE_FILE=${1:-}
APP_NAME=${2:-}
SRC_DB_PATH=${3:-/home/data/app_v0.0.0.db}
if [ -z "$PUBLISH_PROFILE_FILE" ] || [ -z "$APP_NAME" ]; then
echo "Usage: $0 <publish-profile-xml> <webapp-name> [src-db-path]" >&2
exit 2
fi

KUDU_USER=$(grep -o 'userName="[^"]*"' "$PUBLISH_PROFILE_FILE" | head -1 | sed -E 's/userName="([^"]+)"/\1/')
KUDU_PWD=$(grep -o 'userPWD="[^"]*"' "$PUBLISH_PROFILE_FILE" | head -1 | sed -E 's/userPWD="([^"]+)"/\1/')


TS=$(date +%Y%m%d%H%M%S)
BACKUP_PATH="/home/data/Backups/$(basename $SRC_DB_PATH).$TS"

API="https://${APP_NAME}.scm.azurewebsites.net/api/command"
CMD="mkdir -p /home/data/Backups && cp '$SRC_DB_PATH' '$BACKUP_PATH' && ls -l /home/data/Backups"

echo "Backing up $SRC_DB_PATH -> $BACKUP_PATH on ${APP_NAME} via Kudu..."
curl -s -X POST -u "$KUDU_USER:$KUDU_PWD" -H "Content-Type: application/json" -d "{\"command\":\"$CMD\"}" "$API" | jq .

echo "Backup complete: $BACKUP_PATH"
22 changes: 22 additions & 0 deletions scripts/kudu-cleanup-backups.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -euo pipefail
# Usage: ./kudu-cleanup-backups.sh /path/to/publish_profile.xml APP_NAME RETAIN_DAYS
PUBLISH_PROFILE_FILE=${1:-}
APP_NAME=${2:-}
RETAIN_DAYS=${3:-30}
if [ -z "$PUBLISH_PROFILE_FILE" ] || [ -z "$APP_NAME" ]; then
echo "Usage: $0 <publish-profile-xml> <webapp-name> [retain-days]" >&2
exit 2
fi

KUDU_USER=$(grep -o 'userName="[^"]*"' "$PUBLISH_PROFILE_FILE" | head -1 | sed -E 's/userName="([^"]+)"/\1/')
KUDU_PWD=$(grep -o 'userPWD="[^"]*"' "$PUBLISH_PROFILE_FILE" | head -1 | sed -E 's/userPWD="([^"]+)"/\1/')


API="https://${APP_NAME}.scm.azurewebsites.net/api/command"
CMD="find /home/data/Backups -type f -mtime +$RETAIN_DAYS -print -delete || true && ls -l /home/data/Backups"

echo "Cleaning up backups older than $RETAIN_DAYS days on ${APP_NAME} via Kudu..."
curl -s -X POST -u "$KUDU_USER:$KUDU_PWD" -H "Content-Type: application/json" -d "{\"command\":\"$CMD\"}" "$API" | jq .

echo "Cleanup complete."
20 changes: 20 additions & 0 deletions scripts/kudu-create-data-dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
# Usage: ./kudu-create-data-dir.sh /path/to/publish_profile.xml APP_NAME
PUBLISH_PROFILE_FILE=${1:-}
APP_NAME=${2:-}
if [ -z "$PUBLISH_PROFILE_FILE" ] || [ -z "$APP_NAME" ]; then
echo "Usage: $0 <publish-profile-xml> <webapp-name>" >&2
exit 2
fi

KUDU_USER=$(grep -o 'userName="[^"]*"' "$PUBLISH_PROFILE_FILE" | head -1 | sed -E 's/userName="([^"]+)"/\1/')
KUDU_PWD=$(grep -o 'userPWD="[^"]*"' "$PUBLISH_PROFILE_FILE" | head -1 | sed -E 's/userPWD="([^"]+)"/\1/')

API="https://${APP_NAME}.scm.azurewebsites.net/api/command"
CMD='mkdir -p /home/data && chmod 775 /home/data'

echo "Creating /home/data on ${APP_NAME} via Kudu..."
curl -s -X POST -u "$KUDU_USER:$KUDU_PWD" -H "Content-Type: application/json" -d "{\"command\":\"$CMD\"}" "$API" | jq .

echo "Done."