move dev scripts to tools/, migrate to bws, use example.com in docs
Provision server / provision (push) Successful in 7s
Provision server / provision (push) Successful in 7s
- Move new-app.sh, new-service.sh, remove-app.sh from scripts/ to tools/ - Migrate new-app.sh and remove-app.sh from bw to bws - Replace real domains with example.com in documentation and help text
This commit is contained in:
@@ -38,7 +38,7 @@ echo "==> Issuing SSL certificates..."
|
||||
# Stop nginx if running so certbot can bind to port 80
|
||||
docker stop nginx 2>/dev/null || true
|
||||
for conf in "$REPO_DIR"/docker/nginx/conf.d/*.conf; do
|
||||
# Derive cert name from config filename (e.g. timothykim.net.conf -> timothykim.net)
|
||||
# Derive cert name from config filename (e.g. example.com.conf -> example.com)
|
||||
cert_name=$(basename "$conf" .conf)
|
||||
domains=$(grep -oP 'server_name\s+\K[^;]+' "$conf" | tr ' ' '\n' | sort -u)
|
||||
if [ -z "$domains" ]; then
|
||||
|
||||
@@ -1,370 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_URL="https://git.timothykim.net"
|
||||
GITEA_ORG="hantim"
|
||||
TEMPLATE_REPO="static-site-template"
|
||||
SPINNER='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
|
||||
spin_wait() {
|
||||
local secs=$1 msg=$2 start=$3 i=0
|
||||
while [ $i -lt $((secs * 4)) ]; do
|
||||
local elapsed=$(( start + i / 4 ))
|
||||
local sc=${SPINNER:$(( (i) % ${#SPINNER} )):1}
|
||||
printf "\r %s %s (%ds)" "$sc" "$msg" "$elapsed"
|
||||
sleep 0.25
|
||||
i=$((i + 1))
|
||||
done
|
||||
}
|
||||
|
||||
if [ -z "${1:-}" ]; then
|
||||
echo "Usage: ./scripts/new-app.sh <domain>"
|
||||
echo " Example: ./scripts/new-app.sh hcsuzuki.net"
|
||||
echo ""
|
||||
echo "Requires: bw, jq, dig"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP="$1"
|
||||
CONTAINER_NAME="${APP//./_}"
|
||||
SERVER_IP=$(dig +short hantim.net | head -1)
|
||||
|
||||
if [ -z "$SERVER_IP" ]; then
|
||||
echo "Error: Could not resolve hantim.net to get server IP."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$APP" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
|
||||
echo "Error: app name must be alphanumeric (hyphens, dots, underscores allowed)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
if [ -d "$REPO_ROOT/docker/$APP" ]; then
|
||||
echo "Error: docker/$APP already exists."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Check dependencies ---
|
||||
|
||||
if ! command -v bw &>/dev/null; then
|
||||
echo "Error: Bitwarden CLI (bw) is not installed."
|
||||
echo " npm install -g @bitwarden/cli"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &>/dev/null; then
|
||||
echo "Error: jq is not installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v dig &>/dev/null; then
|
||||
echo "Error: dig is not installed."
|
||||
echo " On macOS: brew install bind"
|
||||
echo " On Linux: dnf install bind-utils"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Get secrets (cached in file, or fetch from Bitwarden) ---
|
||||
|
||||
SECRETS_CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/hantim-secrets"
|
||||
|
||||
if [ -f "$SECRETS_CACHE" ]; then
|
||||
echo "Using cached secrets."
|
||||
# shellcheck source=/dev/null
|
||||
source "$SECRETS_CACHE"
|
||||
GITEA_TOKEN="$HANTIM_GITEA_TOKEN"
|
||||
VULTR_API_KEY="$HANTIM_VULTR_API_KEY"
|
||||
DEPLOY_KEY="$HANTIM_DEPLOY_KEY"
|
||||
else
|
||||
if bw status 2>/dev/null | grep -q '"status":"unauthenticated"'; then
|
||||
echo "Log in to Bitwarden:"
|
||||
bw login
|
||||
fi
|
||||
|
||||
if bw status 2>/dev/null | grep -q '"status":"locked"'; then
|
||||
BW_SESSION=$(bw unlock --raw)
|
||||
export BW_SESSION
|
||||
fi
|
||||
|
||||
bw sync --session "${BW_SESSION:-}"
|
||||
GITEA_TOKEN=$(bw get notes hantim-new-app-script --session "${BW_SESSION:-}")
|
||||
VULTR_API_KEY=$(bw get notes hantim-vultr-api-key --session "${BW_SESSION:-}")
|
||||
DEPLOY_KEY=$(bw get item hantim-server-deploy --session "${BW_SESSION:-}" | jq -r '.sshKey.privateKey')
|
||||
|
||||
mkdir -p "$(dirname "$SECRETS_CACHE")"
|
||||
cat > "$SECRETS_CACHE" <<CACHE
|
||||
HANTIM_GITEA_TOKEN='$(echo "$GITEA_TOKEN" | sed "s/'/'\\\\''/g")'
|
||||
HANTIM_VULTR_API_KEY='$(echo "$VULTR_API_KEY" | sed "s/'/'\\\\''/g")'
|
||||
HANTIM_DEPLOY_KEY='$(echo "$DEPLOY_KEY" | sed "s/'/'\\\\''/g")'
|
||||
CACHE
|
||||
chmod 600 "$SECRETS_CACHE"
|
||||
fi
|
||||
|
||||
DEPLOY_KEY_FILE=$(mktemp)
|
||||
echo "$DEPLOY_KEY" > "$DEPLOY_KEY_FILE"
|
||||
chmod 600 "$DEPLOY_KEY_FILE"
|
||||
trap "rm -f $DEPLOY_KEY_FILE" EXIT
|
||||
|
||||
# --- Set up DNS records on Vultr ---
|
||||
|
||||
VULTR_API="https://api.vultr.com/v2"
|
||||
VULTR_AUTH="Authorization: Bearer $VULTR_API_KEY"
|
||||
|
||||
echo "==> Checking DNS zone for $APP on Vultr..."
|
||||
ZONE_CHECK=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
"$VULTR_API/domains/$APP" \
|
||||
-H "$VULTR_AUTH")
|
||||
|
||||
if [ "$ZONE_CHECK" != "200" ]; then
|
||||
echo " Creating DNS zone for $APP..."
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-X POST "$VULTR_API/domains" \
|
||||
-H "$VULTR_AUTH" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"domain\": \"$APP\"}")
|
||||
if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ]; then
|
||||
echo "Error: Failed to create DNS zone (HTTP $HTTP_CODE)"
|
||||
exit 1
|
||||
fi
|
||||
echo " Created DNS zone for $APP"
|
||||
fi
|
||||
|
||||
echo "==> Setting A records for $APP..."
|
||||
RECORDS=$(curl -s "$VULTR_API/domains/$APP/records" -H "$VULTR_AUTH")
|
||||
|
||||
# Delete existing root A records
|
||||
echo "$RECORDS" | jq -r '.records[] | select(.type == "A" and .name == "") | .id' | while read -r id; do
|
||||
echo " Deleting existing A record for $APP (id: $id)"
|
||||
curl -s -X DELETE "$VULTR_API/domains/$APP/records/$id" -H "$VULTR_AUTH"
|
||||
done
|
||||
|
||||
# Delete existing www A records
|
||||
echo "$RECORDS" | jq -r '.records[] | select(.type == "A" and .name == "www") | .id' | while read -r id; do
|
||||
echo " Deleting existing A record for www.$APP (id: $id)"
|
||||
curl -s -X DELETE "$VULTR_API/domains/$APP/records/$id" -H "$VULTR_AUTH"
|
||||
done
|
||||
|
||||
# Create root A record
|
||||
echo " Creating A record: $APP -> $SERVER_IP"
|
||||
RESP=$(mktemp)
|
||||
HTTP_CODE=$(curl -s -o "$RESP" -w "%{http_code}" \
|
||||
-X POST "$VULTR_API/domains/$APP/records" \
|
||||
-H "$VULTR_AUTH" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\": \"\", \"type\": \"A\", \"data\": \"$SERVER_IP\", \"ttl\": 300}")
|
||||
if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "204" ]; then
|
||||
echo "Error: Failed to create A record for $APP (HTTP $HTTP_CODE)"
|
||||
cat "$RESP"
|
||||
rm -f "$RESP"
|
||||
exit 1
|
||||
fi
|
||||
rm -f "$RESP"
|
||||
|
||||
# Create www A record
|
||||
echo " Creating A record: www.$APP -> $SERVER_IP"
|
||||
RESP=$(mktemp)
|
||||
HTTP_CODE=$(curl -s -o "$RESP" -w "%{http_code}" \
|
||||
-X POST "$VULTR_API/domains/$APP/records" \
|
||||
-H "$VULTR_AUTH" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\": \"www\", \"type\": \"A\", \"data\": \"$SERVER_IP\", \"ttl\": 300}")
|
||||
if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "204" ]; then
|
||||
echo "Error: Failed to create A record for www.$APP (HTTP $HTTP_CODE)"
|
||||
cat "$RESP"
|
||||
rm -f "$RESP"
|
||||
exit 1
|
||||
fi
|
||||
rm -f "$RESP"
|
||||
|
||||
echo "==> Waiting for DNS to propagate..."
|
||||
ELAPSED=0
|
||||
for i in $(seq 1 30); do
|
||||
RESOLVED=$(dig +short "$APP" @ns1.vultr.com 2>/dev/null)
|
||||
if [ "$RESOLVED" = "$SERVER_IP" ]; then
|
||||
printf "\r\033[K DNS is live.\n"
|
||||
break
|
||||
fi
|
||||
if [ "$i" = "30" ]; then
|
||||
printf "\r\033[K"
|
||||
echo "Error: DNS for $APP did not resolve to $SERVER_IP after 5 minutes."
|
||||
echo " If this is a new domain, make sure nameservers are set to Vultr on directnic.com."
|
||||
exit 1
|
||||
fi
|
||||
spin_wait 10 "Waiting for DNS..." "$ELAPSED"
|
||||
ELAPSED=$((ELAPSED + 10))
|
||||
done
|
||||
|
||||
# --- Create Gitea repo from template ---
|
||||
|
||||
echo "Creating Gitea repo $GITEA_ORG/$APP from template $TEMPLATE_REPO..."
|
||||
HTTP_CODE=$(curl -s -o /tmp/new-app-response.json -w "%{http_code}" \
|
||||
-X POST "$GITEA_URL/api/v1/repos/$GITEA_ORG/$TEMPLATE_REPO/generate" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"owner\": \"$GITEA_ORG\",
|
||||
\"name\": \"$APP\",
|
||||
\"git_content\": true,
|
||||
\"labels\": false,
|
||||
\"webhooks\": false
|
||||
}")
|
||||
|
||||
if [ "$HTTP_CODE" != "201" ]; then
|
||||
echo "Error: Failed to create repo (HTTP $HTTP_CODE)"
|
||||
cat /tmp/new-app-response.json
|
||||
rm -f /tmp/new-app-response.json
|
||||
exit 1
|
||||
fi
|
||||
rm -f /tmp/new-app-response.json
|
||||
echo " Created: $GITEA_URL/$GITEA_ORG/$APP"
|
||||
|
||||
# --- Create local files in hantim-server ---
|
||||
|
||||
echo "Creating docker/$APP/compose.yml..."
|
||||
mkdir -p "$REPO_ROOT/docker/$APP"
|
||||
cat > "$REPO_ROOT/docker/$APP/compose.yml" <<EOF
|
||||
services:
|
||||
app:
|
||||
image: git.timothykim.net/hantim/$APP:latest
|
||||
restart: unless-stopped
|
||||
container_name: $CONTAINER_NAME
|
||||
networks:
|
||||
- shared
|
||||
|
||||
networks:
|
||||
shared:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "Creating .gitea/workflows/deploy-$APP.yml..."
|
||||
mkdir -p "$REPO_ROOT/.gitea/workflows"
|
||||
cat > "$REPO_ROOT/.gitea/workflows/deploy-$APP.yml" <<'OUTER'
|
||||
name: Deploy APP_PLACEHOLDER
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'docker/APP_PLACEHOLDER/**'
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Deploy via SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
|
||||
chmod 600 ~/.ssh/deploy_key
|
||||
ssh -o StrictHostKeyChecking=accept-new -i ~/.ssh/deploy_key deploy@${{ vars.DEPLOY_HOST }} deploy-APP_PLACEHOLDER
|
||||
OUTER
|
||||
sed -i "s/APP_PLACEHOLDER/$APP/g" "$REPO_ROOT/.gitea/workflows/deploy-$APP.yml"
|
||||
|
||||
echo "Creating docker/nginx/conf.d/$APP.conf..."
|
||||
cat > "$REPO_ROOT/docker/nginx/conf.d/$APP.conf" <<NGINX
|
||||
# Redirect HTTP to HTTPS, bare domain to www
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name $APP www.$APP;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://www.$APP\$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# Redirect bare HTTPS domain to www
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
http2 on;
|
||||
server_name $APP;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/$APP/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/$APP/privkey.pem;
|
||||
|
||||
return 301 https://www.$APP\$request_uri;
|
||||
}
|
||||
|
||||
# Main site
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
http2 on;
|
||||
server_name www.$APP;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/$APP/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/$APP/privkey.pem;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=63072000; preload" always;
|
||||
|
||||
location / {
|
||||
proxy_pass http://$CONTAINER_NAME:80;
|
||||
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;
|
||||
}
|
||||
}
|
||||
NGINX
|
||||
|
||||
# --- Issue SSL cert (zero downtime) ---
|
||||
|
||||
echo "==> Issuing SSL certificate via deploy user..."
|
||||
ssh -o StrictHostKeyChecking=accept-new -i "$DEPLOY_KEY_FILE" deploy@"$SERVER_IP" "cert-$APP"
|
||||
|
||||
# --- Commit and push ---
|
||||
|
||||
echo "==> Committing and pushing hantim-server..."
|
||||
cd "$REPO_ROOT"
|
||||
git add "docker/$APP/compose.yml" ".gitea/workflows/deploy-$APP.yml" "docker/nginx/conf.d/$APP.conf"
|
||||
git commit -m "add $APP"
|
||||
git push
|
||||
|
||||
# --- Trigger initial build ---
|
||||
|
||||
echo "==> Triggering initial build for $APP..."
|
||||
# Wait for template repo to be ready, then dispatch the build workflow
|
||||
ELAPSED=0
|
||||
for i in $(seq 1 60); do
|
||||
TRIGGER_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-X POST "$GITEA_URL/api/v1/repos/$GITEA_ORG/$APP/actions/workflows/build.yml/dispatches" \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"ref": "main"}')
|
||||
[ "$TRIGGER_CODE" != "404" ] && printf "\r\033[K" && break
|
||||
spin_wait 2 "Waiting for repo to be ready..." "$ELAPSED"
|
||||
ELAPSED=$((ELAPSED + 2))
|
||||
done
|
||||
|
||||
if [ "$TRIGGER_CODE" = "204" ]; then
|
||||
echo " Build triggered."
|
||||
else
|
||||
echo " Warning: Could not trigger build (HTTP $TRIGGER_CODE). Check manually:"
|
||||
echo " $GITEA_URL/$GITEA_ORG/$APP/actions"
|
||||
fi
|
||||
|
||||
# --- Verify ---
|
||||
|
||||
echo "==> Waiting for deployment (up to 3 minutes)..."
|
||||
ELAPSED=0
|
||||
for i in $(seq 1 18); do
|
||||
if curl -sf "https://www.$APP" > /dev/null 2>&1; then
|
||||
printf "\r\033[K Site is live at https://www.$APP\n"
|
||||
exit 0
|
||||
fi
|
||||
spin_wait 10 "Waiting for site..." "$ELAPSED"
|
||||
ELAPSED=$((ELAPSED + 10))
|
||||
done
|
||||
printf "\r\033[K"
|
||||
|
||||
echo "WARNING: https://www.$APP is not responding after 3 minutes."
|
||||
echo " Check that:"
|
||||
echo " - DNS for $APP and www.$APP points to $SERVER_IP"
|
||||
echo " - The build completed: $GITEA_URL/$GITEA_ORG/$APP/actions"
|
||||
echo " - The container is running on the server: docker ps"
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ -z "${1:-}" ]; then
|
||||
echo "Usage: ./scripts/new-service.sh <name>"
|
||||
echo " Example: ./scripts/new-service.sh garage"
|
||||
echo ""
|
||||
echo "Creates docker/<name>/compose.yml and .gitea/workflows/deploy-<name>.yml"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP="$1"
|
||||
|
||||
if ! [[ "$APP" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
|
||||
echo "Error: name must be alphanumeric (hyphens, dots, underscores allowed)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
if [ -d "$REPO_ROOT/docker/$APP" ]; then
|
||||
echo "Error: docker/$APP already exists."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Creating docker/$APP/compose.yml..."
|
||||
mkdir -p "$REPO_ROOT/docker/$APP"
|
||||
cat > "$REPO_ROOT/docker/$APP/compose.yml" <<EOF
|
||||
services:
|
||||
$APP:
|
||||
image: TODO
|
||||
restart: unless-stopped
|
||||
container_name: $APP
|
||||
networks:
|
||||
- shared
|
||||
|
||||
networks:
|
||||
shared:
|
||||
external: true
|
||||
EOF
|
||||
|
||||
echo "Creating .gitea/workflows/deploy-$APP.yml..."
|
||||
mkdir -p "$REPO_ROOT/.gitea/workflows"
|
||||
cat > "$REPO_ROOT/.gitea/workflows/deploy-$APP.yml" <<'OUTER'
|
||||
name: Deploy APP_PLACEHOLDER
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'docker/APP_PLACEHOLDER/**'
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Deploy via SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
|
||||
chmod 600 ~/.ssh/deploy_key
|
||||
ssh -o StrictHostKeyChecking=accept-new -i ~/.ssh/deploy_key deploy@${{ vars.DEPLOY_HOST }} deploy-APP_PLACEHOLDER
|
||||
OUTER
|
||||
sed -i "s/APP_PLACEHOLDER/$APP/g" "$REPO_ROOT/.gitea/workflows/deploy-$APP.yml"
|
||||
|
||||
echo "Done. Edit docker/$APP/compose.yml, then commit and push."
|
||||
@@ -1,91 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_URL="https://git.timothykim.net"
|
||||
GITEA_ORG="hantim"
|
||||
|
||||
if [ -z "${1:-}" ]; then
|
||||
echo "Usage: ./scripts/remove-app.sh <domain>"
|
||||
echo " Example: ./scripts/remove-app.sh hcsuzuki.net"
|
||||
echo ""
|
||||
echo "Removes: local files (compose, workflow, nginx conf), Gitea repo."
|
||||
echo "Does NOT remove: DNS records, SSL certs."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP="$1"
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
if ! [[ "$APP" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
|
||||
echo "Error: app name must be alphanumeric (hyphens, dots, underscores allowed)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Check dependencies ---
|
||||
|
||||
if ! command -v bw &>/dev/null; then
|
||||
echo "Error: Bitwarden CLI (bw) is not installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Get secrets (cached in file, or fetch from Bitwarden) ---
|
||||
|
||||
SECRETS_CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/hantim-secrets"
|
||||
|
||||
if [ -f "$SECRETS_CACHE" ]; then
|
||||
echo "Using cached secrets."
|
||||
# shellcheck source=/dev/null
|
||||
source "$SECRETS_CACHE"
|
||||
GITEA_TOKEN="$HANTIM_GITEA_TOKEN"
|
||||
else
|
||||
if bw status 2>/dev/null | grep -q '"status":"unauthenticated"'; then
|
||||
echo "Log in to Bitwarden:"
|
||||
bw login
|
||||
fi
|
||||
|
||||
if bw status 2>/dev/null | grep -q '"status":"locked"'; then
|
||||
BW_SESSION=$(bw unlock --raw)
|
||||
export BW_SESSION
|
||||
fi
|
||||
|
||||
bw sync --session "${BW_SESSION:-}"
|
||||
GITEA_TOKEN=$(bw get notes hantim-new-app-script --session "${BW_SESSION:-}")
|
||||
fi
|
||||
|
||||
# --- Delete Gitea repo ---
|
||||
|
||||
echo "==> Deleting Gitea repo $GITEA_ORG/$APP..."
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-X DELETE "$GITEA_URL/api/v1/repos/$GITEA_ORG/$APP" \
|
||||
-H "Authorization: token $GITEA_TOKEN")
|
||||
|
||||
if [ "$HTTP_CODE" = "204" ]; then
|
||||
echo " Deleted."
|
||||
elif [ "$HTTP_CODE" = "404" ]; then
|
||||
echo " Repo does not exist, skipping."
|
||||
else
|
||||
echo " Warning: unexpected response (HTTP $HTTP_CODE)."
|
||||
fi
|
||||
|
||||
# --- Remove local files ---
|
||||
|
||||
echo "==> Removing local files..."
|
||||
REMOVED=()
|
||||
|
||||
for f in "docker/$APP" ".gitea/workflows/deploy-$APP.yml" "docker/nginx/conf.d/$APP.conf"; do
|
||||
if [ -e "$REPO_ROOT/$f" ]; then
|
||||
git -C "$REPO_ROOT" rm -rf "$f"
|
||||
REMOVED+=("$f")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#REMOVED[@]} -gt 0 ]; then
|
||||
echo "==> Committing and pushing..."
|
||||
cd "$REPO_ROOT"
|
||||
git commit -m "remove $APP"
|
||||
git push
|
||||
else
|
||||
echo " No local files to remove."
|
||||
fi
|
||||
|
||||
echo "Done. DNS records and SSL certs were left in place."
|
||||
Reference in New Issue
Block a user