Sentinel #28
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Sentinel | |
| on: | |
| workflow_dispatch: | |
| schedule: | |
| - cron: "0 7,8 * * 6" | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: sentinel-scan | |
| cancel-in-progress: false | |
| jobs: | |
| scan: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| env: | |
| DOPPLER_TOKEN_PRESENT: ${{ secrets.DOPPLER_TOKEN != '' }} | |
| steps: | |
| - name: Check Europe/Rome schedule | |
| id: schedule | |
| if: github.event_name == 'schedule' | |
| run: | | |
| # Non guardare l'ora a runtime: GitHub ritarda i job schedulati anche | |
| # di oltre un'ora, quindi l'ora di Roma è quasi sempre gia' scivolata | |
| # oltre le 09:00. Decidi in base a QUALE cron ha triggerato + fuso DST. | |
| # 09:00 Europe/Rome = 07:00 UTC in estate (+0200), 08:00 UTC in inverno (+0100). | |
| offset=$(TZ=Europe/Rome date +%z) | |
| sched="${{ github.event.schedule }}" | |
| should_run=false | |
| if [ "$offset" = "+0200" ] && [ "$sched" = "0 7 * * 6" ]; then should_run=true; fi | |
| if [ "$offset" = "+0100" ] && [ "$sched" = "0 8 * * 6" ]; then should_run=true; fi | |
| if [ "$should_run" != "true" ]; then | |
| echo "Cron $sched con offset $offset fuori dalla finestra 09:00 Europe/Rome, skip." | |
| fi | |
| echo "should_run=$should_run" >> "$GITHUB_OUTPUT" | |
| - name: Verifica variabili Doppler | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| env: | |
| DOPPLER_PROJECT: ${{ vars.DOPPLER_PROJECT }} | |
| DOPPLER_CONFIG: ${{ vars.DOPPLER_CONFIG }} | |
| run: | | |
| if [ -z "${DOPPLER_PROJECT:-}" ]; then | |
| echo "::warning::DOPPLER_PROJECT non impostato" | |
| fi | |
| if [ -z "${DOPPLER_CONFIG:-}" ]; then | |
| echo "::warning::DOPPLER_CONFIG non impostata" | |
| fi | |
| if [ "${DOPPLER_TOKEN_PRESENT}" != "true" ]; then | |
| echo "::notice::DOPPLER_TOKEN assente: il fetch non verrà eseguito." | |
| fi | |
| - name: Fetch secrets from Doppler | |
| if: ${{ env.DOPPLER_TOKEN_PRESENT == 'true' && vars.DOPPLER_PROJECT != '' && vars.DOPPLER_CONFIG != '' && (github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true') }} | |
| uses: dopplerhq/secrets-fetch-action@v2.0.0 | |
| with: | |
| doppler-token: ${{ secrets.DOPPLER_TOKEN }} | |
| doppler-project: ${{ vars.DOPPLER_PROJECT }} | |
| doppler-config: ${{ vars.DOPPLER_CONFIG }} | |
| inject-env-vars: true | |
| - name: Apply GitHub email secret fallback | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| env: | |
| GITHUB_SENTINEL_EMAIL_TO: ${{ secrets.SENTINEL_EMAIL_TO }} | |
| GITHUB_SENTINEL_EMAIL_FROM: ${{ secrets.SENTINEL_EMAIL_FROM }} | |
| GITHUB_SENTINEL_GMAIL_USER: ${{ secrets.SENTINEL_GMAIL_USER }} | |
| GITHUB_SENTINEL_GMAIL_APP_PASSWORD: ${{ secrets.SENTINEL_GMAIL_APP_PASSWORD }} | |
| GITHUB_SENTINEL_ICLOUD_USER: ${{ secrets.SENTINEL_ICLOUD_USER }} | |
| GITHUB_SENTINEL_ICLOUD_APP_PASSWORD: ${{ secrets.SENTINEL_ICLOUD_APP_PASSWORD }} | |
| run: | | |
| for name in \ | |
| SENTINEL_EMAIL_TO \ | |
| SENTINEL_EMAIL_FROM \ | |
| SENTINEL_GMAIL_USER \ | |
| SENTINEL_GMAIL_APP_PASSWORD \ | |
| SENTINEL_ICLOUD_USER \ | |
| SENTINEL_ICLOUD_APP_PASSWORD | |
| do | |
| fallback_name="GITHUB_${name}" | |
| if [ -z "${!name:-}" ] && [ -n "${!fallback_name:-}" ]; then | |
| echo "${name}=${!fallback_name}" >> "$GITHUB_ENV" | |
| fi | |
| done | |
| - name: Check email secrets | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: | | |
| missing=0 | |
| for name in \ | |
| SENTINEL_EMAIL_TO \ | |
| SENTINEL_EMAIL_FROM \ | |
| SENTINEL_GMAIL_USER \ | |
| SENTINEL_GMAIL_APP_PASSWORD | |
| do | |
| if [ -z "${!name}" ]; then | |
| echo "::error::Secret mancante: $name" | |
| missing=1 | |
| fi | |
| done | |
| if [ "$missing" -ne 0 ]; then | |
| echo "Configura i secret Gmail prima di avviare la scansione Sentinel." | |
| exit 1 | |
| fi | |
| - name: Checkout | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| uses: actions/checkout@v6 | |
| - name: Setup Node | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - name: Install | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: npm ci | |
| - name: Test | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: npm test | |
| - name: Build | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: npm run build | |
| - name: Scan | |
| id: scan | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: | | |
| set +e | |
| npm run sentinel -- scan | |
| status=$? | |
| echo "exit_code=$status" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| - name: Generate dashboard | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: npm run sentinel -- dashboard | |
| - name: Commit application outputs | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| mkdir -p data snapshots reports | |
| git add data snapshots reports | |
| if git diff --cached --quiet; then | |
| echo "Nessun output da committare." | |
| exit 0 | |
| fi | |
| git commit -m "chore: update sentinel outputs" | |
| git push | |
| - name: Fail on scan errors | |
| if: github.event_name != 'schedule' || steps.schedule.outputs.should_run == 'true' | |
| run: | | |
| if [ "${{ steps.scan.outputs.exit_code }}" != "0" ]; then | |
| echo "Scan conclusa con exit code ${{ steps.scan.outputs.exit_code }}." | |
| exit 1 | |
| fi |