From 40470b15e68a6359e7ecd05e8af80a56bd12cf71 Mon Sep 17 00:00:00 2001 From: pavlov346346-source Date: Fri, 11 Sep 2026 16:54:22 +0300 Subject: [PATCH] Add safe Timeweb hosting deployment workflow --- .github/workflows/deploy-timeweb.yml | 95 ++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 .github/workflows/deploy-timeweb.yml diff --git a/.github/workflows/deploy-timeweb.yml b/.github/workflows/deploy-timeweb.yml new file mode 100644 index 0000000..a10e330 --- /dev/null +++ b/.github/workflows/deploy-timeweb.yml @@ -0,0 +1,95 @@ +name: Deploy Caterium to Timeweb Hosting + +on: + workflow_run: + workflows: ["Caterium QA"] + types: [completed] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: caterium-timeweb-production + cancel-in-progress: false + +jobs: + deploy: + if: >- + github.event_name == 'workflow_dispatch' || + (github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.head_branch == 'production') + runs-on: ubuntu-latest + env: + TIMEWEB_HOST: ${{ secrets.TIMEWEB_HOST }} + TIMEWEB_USER: ${{ secrets.TIMEWEB_USER }} + TIMEWEB_SSH_KEY: ${{ secrets.TIMEWEB_SSH_KEY }} + TIMEWEB_REMOTE_PATH: ${{ secrets.TIMEWEB_REMOTE_PATH }} + + steps: + - name: Check Timeweb configuration + id: config + shell: bash + run: | + missing=0 + for name in TIMEWEB_HOST TIMEWEB_USER TIMEWEB_SSH_KEY TIMEWEB_REMOTE_PATH; do + if [ -z "${!name}" ]; then + echo "::notice::$name is not configured yet" + missing=1 + fi + done + + if [ "$missing" -eq 0 ]; then + echo "ready=true" >> "$GITHUB_OUTPUT" + else + echo "ready=false" >> "$GITHUB_OUTPUT" + echo "Timeweb deployment is prepared but inactive until all four repository secrets are configured." + fi + + - name: Checkout tested production revision + if: steps.config.outputs.ready == 'true' + uses: actions/checkout@v4 + with: + ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || 'production' }} + + - name: Configure SSH + if: steps.config.outputs.ready == 'true' + shell: bash + run: | + install -m 700 -d "$HOME/.ssh" + printf '%s\n' "$TIMEWEB_SSH_KEY" > "$HOME/.ssh/timeweb_deploy_key" + chmod 600 "$HOME/.ssh/timeweb_deploy_key" + ssh-keyscan -p 22 -H "$TIMEWEB_HOST" >> "$HOME/.ssh/known_hosts" + chmod 600 "$HOME/.ssh/known_hosts" + + - name: Verify Timeweb target + if: steps.config.outputs.ready == 'true' + shell: bash + run: | + test -f public/index.html + ssh -p 22 -i "$HOME/.ssh/timeweb_deploy_key" \ + -o BatchMode=yes \ + -o IdentitiesOnly=yes \ + "$TIMEWEB_USER@$TIMEWEB_HOST" \ + "mkdir -p -- '$TIMEWEB_REMOTE_PATH'" + + - name: Deploy public directory + if: steps.config.outputs.ready == 'true' + shell: bash + run: | + rsync -az --delete --checksum \ + --exclude='.htaccess' \ + --exclude='.well-known/' \ + -e "ssh -p 22 -i $HOME/.ssh/timeweb_deploy_key -o BatchMode=yes -o IdentitiesOnly=yes" \ + public/ \ + "$TIMEWEB_USER@$TIMEWEB_HOST:$TIMEWEB_REMOTE_PATH/" + + - name: Verify deployed entry point + if: steps.config.outputs.ready == 'true' + shell: bash + run: | + ssh -p 22 -i "$HOME/.ssh/timeweb_deploy_key" \ + -o BatchMode=yes \ + -o IdentitiesOnly=yes \ + "$TIMEWEB_USER@$TIMEWEB_HOST" \ + "test -s '$TIMEWEB_REMOTE_PATH/index.html'"