A lightweight, cost-effective automation pipeline for downloading, validating, and deploying macOS application packages to Jamf Pro using GitHub Actions.
- π€ Automated Downloads: Direct downloads of 6 enterprise macOS applications
- π Code Signature Verification: Team ID verification using Apple Developer certificates
- π Security Scanning: Optional VirusTotal malware scanning
- π¦ Format Conversion: Automatic DMG to PKG conversion for Jamf compatibility
- βοΈ Jamf Pro Integration: Automatic upload to your Jamf Pro server
- π° Cost Effective: Runs on Ubuntu ($0.008/minute) instead of macOS ($0.08/minute)
- π Detailed Reporting: JSON reports and GitHub Actions summaries
- π§ Local Testing: Test the entire pipeline locally before deployment
This MVP implementation includes:
- 6 enterprise applications:
- Google Chrome
- Mozilla Firefox
- Zoom
- 1Password 8
- Jamf Connect
- Okta Verify
- Team ID verification (more reliable than SHA256 - doesn't change between versions)
- DMG to PKG conversion for apps distributed as disk images
- Simple Jamf Pro upload with automatic format handling
- Daily automated runs via GitHub Actions
- GitHub account with Actions enabled
- Jamf Pro instance with API access
- VirusTotal API key (free tier)
- Python 3.11+
git clone https://github.com/YOUR_USERNAME/cloud-autopkg-runner.git
cd cloud-autopkg-runnerAdd these secrets to your GitHub repository (Settings β Secrets β Actions):
VIRUSTOTAL_API_KEY=your_virustotal_api_key
JAMF_URL=https://your-instance.jamfcloud.com
JAMF_USERNAME=your_api_username
JAMF_PASSWORD=your_api_passwordThe pipeline uses Team ID verification by default, which is more reliable than SHA256 hashes since Team IDs don't change between app versions.
Check config/apps.json to see the configured apps and their Team IDs.
# Full test with all features
export VIRUSTOTAL_API_KEY="your_virustotal_api_key"
export JAMF_URL="https://your-instance.jamfcloud.com"
export JAMF_USERNAME="your_username"
export JAMF_PASSWORD="your_password"
./test_local.shgit add .
git commit -m "Initial MVP setup"
git push origin mainThen trigger manually:
- Go to Actions tab in GitHub
- Select "AutoPkg MVP Runner"
- Click "Run workflow"
cloud-autopkg-runner/
βββ .github/
β βββ workflows/
β βββ autopkg-mvp.yml # GitHub Actions workflow
βββ scripts/
β βββ download_and_validate.py # Download & signature verification
β βββ jamf_upload.py # Jamf Pro upload
β βββ verify_signature.py # Team ID verification
β βββ dmg_to_pkg.py # DMG to PKG converter
β βββ extract_pkg_from_dmg.py # Extract PKG from DMG
βββ config/
β βββ apps.json # Application configurations
βββ reference/
β βββ Installomator.sh # Reference for 700+ app configs
βββ downloads/ # Downloaded packages (git-ignored)
βββ reports/ # Processing reports
βββ test_local.sh # Local testing script
βββ FUTURE_FEATURES.md # Roadmap and ideas
βββ README.md # This file
Configure applications in config/apps.json:
{
"apps": [
{
"name": "GoogleChrome",
"filename": "GoogleChrome.pkg",
"url": "https://dl.google.com/chrome/...",
"team_id": "EQHXZ8M8AV",
"notes": "Uses Team ID verification instead of SHA256"
},
{
"name": "JamfConnect",
"filename": "JamfConnect.dmg",
"url": "https://files.jamfconnect.com/JamfConnect.dmg",
"team_id": "483DWKW443",
"type": "pkgInDmg",
"notes": "PKG will be extracted from DMG"
}
]
}Key Configuration Options:
team_id: Apple Developer Team ID for signature verification (preferred)sha256: SHA256 hash for verification (fallback if no team_id)type: Package type (pkg,dmg,pkgInDmg)
Edit .github/workflows/autopkg-mvp.yml to change the schedule:
schedule:
- cron: '0 2 * * *' # Daily at 2 AM UTC# Test everything
./test_local.sh
# Skip download (use existing files)
./test_local.sh --skip-download
# Skip upload (download and validate only)
./test_local.sh --skip-upload
# Test specific app
./test_local.sh --app GoogleChrome- Go to Actions tab
- Select "AutoPkg MVP Runner"
- Click "Run workflow"
- Optional: Check "Skip Jamf upload" for test mode
Reports are generated in JSON format and saved to reports/:
results.json- Latest run resultsresults_YYYYMMDD_HHMMSS.json- Timestamped resultsupload_YYYYMMDD_HHMMSS.json- Upload results
Example report structure:
{
"timestamp": "2024-01-15T10:30:00",
"apps": [
{
"name": "GoogleChrome",
"status": "success",
"size_mb": 234.5,
"virustotal": {
"malicious": 0,
"harmless": 72
}
}
]
}This MVP includes multiple security layers:
- HTTPS Downloads - All packages downloaded over TLS
- SHA256 Verification - Ensures package integrity
- VirusTotal Scanning - Checks against 70+ antivirus engines
- Secure Secrets - GitHub encrypted secrets for credentials
| Component | Cost | Notes |
|---|---|---|
| GitHub Actions (Ubuntu) | ~$0.04/run | 5 minutes @ $0.008/min |
| VirusTotal API | Free | 500 requests/day |
| Monthly Total | ~$1.20 | 30 daily runs |
Compare to macOS runners: ~$12/month (10x more expensive)
- View run history
- Check logs for each step
- Download artifacts (packages & reports)
GitHub Actions sends email notifications for:
- Failed scheduled runs
- Manual run completions
Failed scheduled runs create GitHub issues automatically
VirusTotal API Rate Limiting
- Free tier: 4 requests/minute
- Solution: Runs are spaced out automatically
Package Download Fails
- Check if URL has changed
- Verify network connectivity
- Update URL in
config/apps.json
Hash Mismatch
- Package was updated
- Run locally to get new hash
- Update
config/apps.json
Jamf Upload Fails
- Verify API credentials
- Check API user permissions
- Ensure Jamf Pro is accessible
Run locally with verbose output:
python3 scripts/download_and_validate.py
python3 scripts/jamf_upload.pyAfter MVP success, consider adding:
- Phase 2: More applications (10+)
- Phase 3: AutoPkg recipe integration
- Phase 4: Code signature verification (requires macOS runner)
- Phase 5: Slack/Teams notifications
- Phase 6: Web dashboard
- Fork the repository
- Create a feature branch
- Make your changes
- Test locally
- Submit a pull request
MIT License - See LICENSE file for details
- AutoPkg community for inspiration
- Jamf Pro for API documentation
- VirusTotal for malware scanning API
- Create an issue for bugs/features
- Check existing issues for solutions
- Review workflow logs for debugging
Version: 1.0.0-MVP
Last Updated: January 2024
Status: Production Ready π’