Skip to content

Add Scheduled Job #8

Description

@leogdion

Overview

This issue adds a scheduled GitHub Actions workflow that automatically syncs macOS restore images, Xcode versions, and Swift versions to CloudKit every 12 hours.

Implementation Summary

Code Changes

  1. BushelCloudKitService.swift - Added PEM string initializer + environment parameter

    • New init(containerIdentifier:keyID:pemString:environment:) for CI/CD environments
    • Accepts PEM content directly from environment variables
    • Eliminates need for file I/O in GitHub Actions
    • Environment parameter (.development or .production) with default to .development
  2. SyncEngine.swift - Support for both authentication methods + environment selection

    • Updated initializer to accept both privateKeyPath and pemString
    • Added environment parameter for dev/prod selection
    • Automatically chooses appropriate BushelCloudKitService initializer
    • Backward compatible with existing file-based approach
  3. SyncCommand.swift - Environment variable support + environment selection

    • New --pem-content command-line option
    • New --environment flag (development/production)
    • Reads from CLOUDKIT_PRIVATE_KEY environment variable
    • Reads from CLOUDKIT_ENVIRONMENT environment variable
    • Updated help text with CI/CD examples

New Files

  1. .github/workflows/cloudkit-sync.yml - Scheduled workflow

    • Runs every 12 hours (00:00 and 12:00 UTC)
    • Uses ubuntu-latest with Swift 6.2
    • Caches .build directory for faster runs (2-4 minutes after first run)
    • Respects fetch intervals (no --force flag)
    • Currently configured for development environment
  2. .github/CLOUDKIT_SYNC_SETUP.md - Setup documentation

    • Step-by-step GitHub Secrets configuration
    • Troubleshooting guide
    • Security best practices
    • Performance and cost information
    • Environment switching instructions

Configuration Required

To enable the workflow, add these GitHub Secrets (Settings → Secrets and variables → Actions):

  • CLOUDKIT_KEY_ID - 32-character Server-to-Server Key ID
  • CLOUDKIT_PRIVATE_KEY - Full PEM file content (including headers/footers)

Note: A single S2S key works for both development and production environments. The environment is selected via the CLOUDKIT_ENVIRONMENT variable in the workflow file.

See .github/CLOUDKIT_SYNC_SETUP.md for detailed setup instructions.

Features

  • Cost-efficient: ~120-240 Linux minutes/month (within free tier)
  • Secure: PEM content never written to disk
  • Fast: Build caching reduces runtime to 2-4 minutes (after first run)
  • Reliable: Respects fetch intervals to avoid API rate limits
  • Flexible: Manual trigger available via workflow_dispatch
  • Environment support: Same key works for both dev and production (just change CLOUDKIT_ENVIRONMENT variable)

Environment Support

The workflow supports both development and production CloudKit environments:

  • Development (default): Safe for testing, free API calls
  • Production: Real user data, same key but different environment setting

To switch to production, simply change CLOUDKIT_ENVIRONMENT: development to CLOUDKIT_ENVIRONMENT: production in the workflow file.

Testing

Test the workflow:

  1. Configure GitHub Secrets (see setup guide)
  2. Go to Actions → Scheduled CloudKit Sync
  3. Click "Run workflow" to trigger manually
  4. Monitor logs for success

Documentation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions