name: Daytona Snapshot Drift on: schedule: - cron: "17 9 * * *" workflow_dispatch: permissions: contents: read jobs: check-snapshot-pin: name: Compare production pin with latest release if: github.repository == 'different-ai/openwork' runs-on: blacksmith-4vcpu-ubuntu-2404 env: DAYTONA_CLOUD_ENV_GROUP_ID: ${{ vars.DAYTONA_CLOUD_ENV_GROUP_ID }} DAYTONA_SNAPSHOT_NAME_BASE: ${{ vars.DAYTONA_SNAPSHOT_NAME_BASE }} RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} steps: - name: Check drift configuration id: config shell: bash run: | set -euo pipefail missing="" [ -z "${DAYTONA_CLOUD_ENV_GROUP_ID:-}" ] && missing="$missing DAYTONA_CLOUD_ENV_GROUP_ID" [ -z "${RENDER_API_KEY:-}" ] && missing="$missing RENDER_API_KEY" if [ -n "$missing" ]; then echo "::notice::Skipping Daytona snapshot drift check; missing GitHub configuration:$missing." echo "enabled=false" >> "$GITHUB_OUTPUT" exit 0 fi echo "enabled=true" >> "$GITHUB_OUTPUT" - name: Checkout if: steps.config.outputs.enabled == 'true' uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: fetch-depth: 0 - name: Read production snapshot pin if: steps.config.outputs.enabled == 'true' id: current shell: bash run: | set -euo pipefail pin="$(node scripts/update-daytona-snapshot-pin.mjs \ --env-group-id "$DAYTONA_CLOUD_ENV_GROUP_ID" \ --read)" base_name="${DAYTONA_SNAPSHOT_NAME_BASE:-openwork}" echo "pin=$pin" >> "$GITHUB_OUTPUT" if [[ "$pin" =~ ^${base_name}-dev-([0-9a-f]{7,})$ ]]; then echo "channel=dev" >> "$GITHUB_OUTPUT" echo "sha=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT" else echo "channel=release" >> "$GITHUB_OUTPUT" fi - name: Check dev channel snapshot pin if: steps.config.outputs.enabled == 'true' && steps.current.outputs.channel == 'dev' shell: bash env: CURRENT_PIN: ${{ steps.current.outputs.pin }} SHORT_SHA: ${{ steps.current.outputs.sha }} run: | set -euo pipefail git fetch origin dev if ! full_sha="$(git rev-parse --verify "${SHORT_SHA}^{commit}" 2>/dev/null)"; then echo "::error::nightly dev snapshot appears stale/broken: ${SHORT_SHA} does not resolve to a commit" exit 1 fi if ! git merge-base --is-ancestor "$full_sha" origin/dev; then echo "::error::nightly dev snapshot appears stale/broken: ${full_sha} is not on origin/dev" exit 1 fi commit_time="$(git show -s --format=%ct "$full_sha")" if [ "$(( $(date +%s) - commit_time ))" -gt 172800 ]; then echo "::error::nightly dev snapshot appears stale/broken" exit 1 fi echo "Dev channel pin healthy: ${CURRENT_PIN}" >> "$GITHUB_STEP_SUMMARY" - name: Resolve expected snapshot from latest release if: steps.config.outputs.enabled == 'true' && steps.current.outputs.channel == 'release' id: expected shell: bash env: GH_TOKEN: ${{ github.token }} run: | set -euo pipefail release_tag="$(gh api "repos/${GITHUB_REPOSITORY}/releases?per_page=100" \ --jq 'map(select(.draft == false))[0].tag_name')" if [[ ! "$release_tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then echo "::error::Newest published GitHub release returned invalid tag: ${release_tag}" exit 1 fi base_name="${DAYTONA_SNAPSHOT_NAME_BASE:-openwork}" snapshot_name="${base_name}-${release_tag#v}" echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT" echo "snapshot_name=$snapshot_name" >> "$GITHUB_OUTPUT" echo "Expected snapshot for ${release_tag}: ${snapshot_name}" - name: Compare production snapshot pin if: steps.config.outputs.enabled == 'true' && steps.current.outputs.channel == 'release' shell: bash env: EXPECTED_SNAPSHOT_NAME: ${{ steps.expected.outputs.snapshot_name }} run: | set -euo pipefail node scripts/update-daytona-snapshot-pin.mjs \ --env-group-id "$DAYTONA_CLOUD_ENV_GROUP_ID" \ --snapshot "$EXPECTED_SNAPSHOT_NAME" \ --compare