A comprehensive backup solution for GitHub repositories that creates compressed ZIP archives and stores them in Azure Blob Storage with Teams/Power Automate compatible notifications.
- Compressed ZIP backups of complete repository mirrors
- Teams/Power Automate compatible notifications with success/failure status
- Success tracking with detailed repository lists
- Modular architecture for easy local testing and development
- Line-for-line identical code extraction from original workflow
backup/
├── .github/workflows/
│ └── backup-repos-modular.yml # New modular workflow
├── scripts/ # Modular script components
│ ├── setup.sh # Environment setup
│ ├── backup-repo.sh # Single repository backup
│ ├── send-webhook.sh # Webhook notifications
│ ├── process-repos.sh # Repository processing
│ ├── main.sh # Main orchestration
│ └── run-workflow.sh # GitHub Actions entry point
├── repos.txt # Repository list
└── README.md # This file
Edit repos.txt to include the repositories you want to backup:
https://github.com/username/repo1.git
https://github.com/username/repo2.git
https://github.com/username/private-repo.git
Configure these secrets in your GitHub repository:
AZURE_STORAGE_ACCOUNT: Your Azure storage account nameAZURE_STORAGE_KEY: Your Azure storage account keyBACKUP_TOKEN: GitHub Personal Access Token (for private repos)WEBHOOK_URL: Teams/Power Automate webhook URL (optional)
The workflow runs automatically daily at 2 AM UTC, or you can trigger it manually via GitHub Actions.
The backup system has been modularized for easy local testing and development. Each component can be tested independently.
- Bash shell (Linux, macOS, or Windows with WSL/Git Bash)
- Azure CLI installed and configured
- Git installed
- zip utility available
On Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y git zip jq curl
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bashOn macOS:
brew install git zip jq curl azure-cliOn Windows (with Chocolatey):
choco install git zip jq curl azure-cliCopy the environment template and fill in your values:
cp env.example .envEdit .env with your actual credentials:
# Required
AZURE_STORAGE_ACCOUNT=your-storage-account-name
AZURE_STORAGE_KEY=your-storage-account-key
GITHUB_TOKEN=your-github-personal-access-token
# Optional
WEBHOOK_URL=https://your-webhook-url
CONTAINER_NAME=repo-backups
GITHUB_REPOSITORY=username/repository-namechmod +x scripts/*.shThe modular architecture allows you to test each component independently:
# Test webhook with success message
scripts/send-webhook.sh true "Test success message" "test-repo"
# Test webhook with failure message
scripts/send-webhook.sh false "Test failure message" "test-repo"# Test backup of a specific repository
scripts/backup-repo.sh https://github.com/username/repo.git# Test the complete backup process
scripts/run-workflow.shYou can also test components directly without the test script:
# Test environment setup
scripts/setup.sh
# Test repository processing
scripts/process-repos.sh
# Test main orchestration
scripts/main.shexport GITHUB_TOKEN="" # No token needed for public repos
scripts/backup-repo.sh https://github.com/microsoft/vscode.gitexport GITHUB_TOKEN="your-personal-access-token"
scripts/backup-repo.sh https://github.com/username/private-repo.gitexport WEBHOOK_URL="https://your-teams-webhook-url"
scripts/send-webhook.sh true "Test message" "test-repo"# Verify all required variables are set
echo "AZURE_STORAGE_ACCOUNT: $AZURE_STORAGE_ACCOUNT"
echo "AZURE_STORAGE_KEY: $AZURE_STORAGE_KEY"
echo "GITHUB_TOKEN: $GITHUB_TOKEN"
echo "WEBHOOK_URL: $WEBHOOK_URL"# Test Azure storage connectivity
az storage account show --name "$AZURE_STORAGE_ACCOUNT"
az storage container list --account-name "$AZURE_STORAGE_ACCOUNT" --account-key "$AZURE_STORAGE_KEY"# Test GitHub token validity
curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user# Run with verbose output
bash -x scripts/backup-repo.sh https://github.com/username/repo.git- Make changes to individual scripts in the
scripts/directory - Test locally using the individual script commands
- Verify functionality matches the original workflow
- Commit changes and push to trigger GitHub Actions
The system sends Teams/Power Automate compatible notifications with:
- Success/Failure status with color coding
- Successful repositories list
- Direct link to workflow run
- Detailed statistics (total, succeeded, failed)
- Timestamp and repository information
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "00FF00",
"summary": "Repository Backup ✅ Success",
"sections": [
{
"activityTitle": "GitHub Repository Backup",
"activitySubtitle": "2024-01-15 14:30:00 UTC",
"facts": [
{ "name": "Status", "value": "✅ Success" },
{
"name": "Result",
"value": "Backup successful: All 3 repositories backed up"
},
{
"name": "Successful Repositories",
"value": "repo1, repo2, repo3"
},
{ "name": "Workflow", "value": "repository-backup" }
]
}
],
"potentialAction": [
{
"@type": "OpenUri",
"name": "View Workflow Run",
"targets": [
{
"uri": "https://github.com/username/repo/actions/runs/123456789"
}
]
}
]
}- Environment Setup: Install Azure CLI and create storage container
- Repository Reading: Parse
repos.txtand load repositories into array - Backup Processing: For each repository:
- Clone with mirror option
- Create ZIP archive with timestamp
- Upload to Azure Blob Storage
- Track success/failure
- ZIP archives stored as
{repo-name}_{YYYYMMDD_HHMMSS}.zip - Webhook notifications with success details and workflow link
Azure Blob Storage Container: repo-backups/
├── repo1_20240115_143000.zip
├── repo2_20240115_143000.zip
└── repo3_20240115_143000.zip
No retention policy - backed-up data stays forever. This reduces complexity and eliminates the risk of accidental data loss.
Edit the cron expression in .github/workflows/backup-repos-modular.yml:
schedule:
- cron: "0 2 * * *" # Daily at 2 AM UTC
- cron: "0 */6 * * *" # Every 6 hours
- cron: "0 9 * * 1-5" # Weekdays at 9 AM UTCThe modular architecture makes it easy to add new features:
- Add new scripts to the
scripts/directory - Test locally using the test script
- Integrate into the main workflow
| Variable | Required | Description |
|---|---|---|
AZURE_STORAGE_ACCOUNT |
Yes | Azure storage account name |
AZURE_STORAGE_KEY |
Yes | Azure storage account key |
GITHUB_TOKEN |
Yes | GitHub Personal Access Token |
WEBHOOK_URL |
No | Teams/Power Automate webhook URL |
CONTAINER_NAME |
No | Azure container name (default: repo-backups) |
- Check if repository is private and
GITHUB_TOKENis set - Verify repository URL is correct
- Ensure token has appropriate permissions
- Verify Azure storage credentials
- Check network connectivity
- Ensure storage account has sufficient space
- Check
WEBHOOK_URLis set correctly - Verify webhook URL is accessible
- Check Teams/Power Automate configuration
chmod +x scripts/*.sh- Check logs in GitHub Actions
- Test locally using the individual script commands
- Verify environment variables are set correctly
- Check Azure and GitHub connectivity
The modular version is functionally identical to the original workflow:
- Same code - extracted line-for-line
- Same behavior - identical output and results
- Same configuration - uses same secrets and settings
- Same schedule - runs at same time
To migrate:
- Deploy the new modular workflow
- Test alongside the original workflow
- Verify results match
- Switch to modular workflow
- Remove original workflow
- Local Testing: Test components independently
- Faster Development: Iterate quickly with local testing
- Better Debugging: Isolate issues to specific components
- Easier Maintenance: Modify individual components
- Code Reuse: Use components in other projects
- Zero Risk: Identical functionality to original workflow