Use the stable self-hosted runner for cPanel API calls and install lftp job-locally without sudo.
100 lines
3.7 KiB
YAML
100 lines
3.7 KiB
YAML
name: cPanel Root Audit and Restore
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
mode:
|
|
description: Audit is read-only; restore exchanges public_html with a retained recovery entry.
|
|
required: true
|
|
default: audit
|
|
type: choice
|
|
options:
|
|
- audit
|
|
- restore
|
|
recovery:
|
|
description: Exact recovery entry reported by an audit, for example public_html.recovery-20260720.
|
|
required: false
|
|
type: string
|
|
state_token:
|
|
description: Exact 64-character audit-metadata state token reported by the audit.
|
|
required: false
|
|
type: string
|
|
confirmation:
|
|
description: For restore, type RESTORE <recovery> TO <webroot> STATE <state-token> exactly.
|
|
required: false
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: frontend-production
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
audit-or-restore:
|
|
runs-on: [self-hosted, Linux, X64, default]
|
|
timeout-minutes: 10
|
|
environment:
|
|
name: frontend-production
|
|
url: ${{ vars.PRODUCTION_FRONTEND_URL || 'https://truckwash.io' }}
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@v5
|
|
with:
|
|
node-version: 22
|
|
|
|
- name: Audit cPanel primary webroot
|
|
if: inputs.mode == 'audit'
|
|
id: audit
|
|
run: node scripts/release/cpanel-root.mjs audit
|
|
env:
|
|
NODE_OPTIONS: --use-system-ca
|
|
PRODUCTION_CPANEL_USER: ${{ secrets.PRODUCTION_CPANEL_USER }}
|
|
PRODUCTION_CPANEL_API_TOKEN: ${{ secrets.PRODUCTION_CPANEL_API_TOKEN }}
|
|
PRODUCTION_CPANEL_API_URL: ${{ vars.PRODUCTION_CPANEL_API_URL }}
|
|
PRODUCTION_CPANEL_PATH: ${{ vars.PRODUCTION_CPANEL_PATH }}
|
|
PRODUCTION_CPANEL_WEBROOT: ${{ vars.PRODUCTION_CPANEL_WEBROOT || 'public_html' }}
|
|
PRODUCTION_FRONTEND_URL: ${{ vars.PRODUCTION_FRONTEND_URL || 'https://truckwash.io' }}
|
|
CPANEL_ROOT_REPORT_PATH: output/cpanel-root/audit.json
|
|
|
|
- name: Validate restore inputs
|
|
if: inputs.mode == 'restore'
|
|
env:
|
|
RECOVERY: ${{ inputs.recovery }}
|
|
STATE_TOKEN: ${{ inputs.state_token }}
|
|
CONFIRMATION: ${{ inputs.confirmation }}
|
|
WEBROOT: ${{ vars.PRODUCTION_CPANEL_WEBROOT || 'public_html' }}
|
|
run: |
|
|
test -n "$RECOVERY"
|
|
[[ "$STATE_TOKEN" =~ ^[a-f0-9]{64}$ ]]
|
|
test "$CONFIRMATION" = "RESTORE $RECOVERY TO $WEBROOT STATE $STATE_TOKEN"
|
|
|
|
- name: Restore retained cPanel webroot
|
|
if: inputs.mode == 'restore'
|
|
run: node scripts/release/cpanel-root.mjs restore
|
|
env:
|
|
NODE_OPTIONS: --use-system-ca
|
|
PRODUCTION_CPANEL_USER: ${{ secrets.PRODUCTION_CPANEL_USER }}
|
|
PRODUCTION_CPANEL_API_TOKEN: ${{ secrets.PRODUCTION_CPANEL_API_TOKEN }}
|
|
PRODUCTION_CPANEL_API_URL: ${{ vars.PRODUCTION_CPANEL_API_URL }}
|
|
PRODUCTION_CPANEL_PATH: ${{ vars.PRODUCTION_CPANEL_PATH }}
|
|
PRODUCTION_CPANEL_WEBROOT: ${{ vars.PRODUCTION_CPANEL_WEBROOT || 'public_html' }}
|
|
PRODUCTION_FRONTEND_URL: ${{ vars.PRODUCTION_FRONTEND_URL || 'https://truckwash.io' }}
|
|
CPANEL_ROOT_RECOVERY: ${{ inputs.recovery }}
|
|
CPANEL_ROOT_STATE_TOKEN: ${{ inputs.state_token }}
|
|
CPANEL_ROOT_CONFIRMATION: ${{ inputs.confirmation }}
|
|
CPANEL_ROOT_REPORT_PATH: output/cpanel-root/restore.json
|
|
|
|
- name: Upload cPanel root report
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: cpanel-root-${{ inputs.mode }}-${{ github.run_id }}
|
|
path: output/cpanel-root
|
|
if-no-files-found: ignore
|
|
retention-days: 30
|