diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 220bf614..2694419b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,21 +9,27 @@ updates: day: "monday" time: "09:00" timezone: "UTC" - target-branch: "main" + target-branch: "development" # All updates go to development first commit-message: prefix: "chore(deps)" include: "scope" labels: - "dependencies" - "security" + - "automated" + - "needs-review" open-pull-requests-limit: 10 pull-request-branch-name: separator: "-" + prefix: "deps/dev-" + versioning-strategy: "auto" + security-updates-only: false reviewers: - "botshelomokoka" - versioning-strategy: "auto" + allow: + - dependency-type: "direct" + - dependency-type: "indirect" ignore: - # Ignore patch updates for non-critical dependencies - dependency-name: "*" update-types: ["version-update:semver-patch"] @@ -50,12 +56,19 @@ updates: day: "monday" time: "09:00" timezone: "UTC" - labels: - - "dependencies" - - "github-actions" + target-branch: "development" # All CI updates go to development first commit-message: - prefix: "chore(actions)" + prefix: "chore(ci)" include: "scope" + labels: + - "ci-cd" + - "dependencies" + - "automated" + - "needs-review" + pull-request-branch-name: + separator: "-" + prefix: "ci/dev-" + security-updates-only: false reviewers: - "botshelomokoka" diff --git a/.github/workflows/branch_maintenance.yml b/.github/workflows/branch_maintenance.yml new file mode 100644 index 00000000..3b7869ff --- /dev/null +++ b/.github/workflows/branch_maintenance.yml @@ -0,0 +1,120 @@ +name: Branch Maintenance and Alignment + +on: + schedule: + - cron: '0 0 * * SUN' # Run weekly on Sunday + workflow_dispatch: # Allow manual trigger + inputs: + force_cleanup: + description: 'Force cleanup of stale branches' + required: false + default: 'false' + +jobs: + branch-maintenance: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Fetch all history + + - name: Setup Git + run: | + git config user.name "GitHub Actions" + git config user.email "actions@github.com" + + - name: Analyze Branches + id: analyze + run: | + # List all branches with their last commit info + echo "Analyzing branches and their commit history..." + git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)|%(committerdate:iso8601)|%(committername)|%(subject)' > branch_analysis.txt + + # Identify stale branches (no commits in 30 days, except protected branches) + echo "Identifying stale branches..." + while IFS='|' read -r branch date author message; do + if [[ ! "$branch" =~ ^(main|development|master|release)$ ]] && [[ $(date -d "$date" +%s) -lt $(date -d "30 days ago" +%s) ]]; then + echo "$branch" >> stale_branches.txt + fi + done < branch_analysis.txt + + # Identify merged branches + echo "Identifying merged branches..." + git branch --merged development | grep -v "^\*" | grep -vE "^(\s*development|\s*main|\s*master)$" > merged_branches.txt + + - name: Generate Branch Report + run: | + echo "# Branch Analysis Report" > branch_report.md + echo "## Active Branches" >> branch_report.md + echo "\`\`\`" >> branch_report.md + git branch -r --sort=-committerdate | grep -v HEAD >> branch_report.md + echo "\`\`\`" >> branch_report.md + + echo "## Stale Branches" >> branch_report.md + echo "\`\`\`" >> branch_report.md + cat stale_branches.txt >> branch_report.md + echo "\`\`\`" >> branch_report.md + + echo "## Merged Branches" >> branch_report.md + echo "\`\`\`" >> branch_report.md + cat merged_branches.txt >> branch_report.md + echo "\`\`\`" >> branch_report.md + + echo "## Recent Commits per Branch" >> branch_report.md + echo "\`\`\`" >> branch_report.md + cat branch_analysis.txt >> branch_report.md + echo "\`\`\`" >> branch_report.md + + - name: Create Issue with Branch Report + uses: actions/github-script@v6 + with: + script: | + const fs = require('fs'); + const report = fs.readFileSync('branch_report.md', 'utf8'); + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: 'Weekly Branch Maintenance Report', + body: report, + labels: ['maintenance', 'branch-cleanup'] + }); + + - name: Cleanup Approved Branches + if: github.event.inputs.force_cleanup == 'true' + run: | + # Delete merged branches + while read branch; do + if [ -n "$branch" ]; then + git push origin --delete $branch + echo "Deleted merged branch: $branch" + fi + done < merged_branches.txt + + # Delete stale branches + while read branch; do + if [ -n "$branch" ]; then + git push origin --delete $branch + echo "Deleted stale branch: $branch" + fi + done < stale_branches.txt + + - name: Align Branch Structure + run: | + # Ensure development branch exists + if ! git show-ref --verify --quiet refs/remotes/origin/development; then + git checkout -b development main + git push origin development + fi + + # Ensure proper branch protection + gh api repos/$GITHUB_REPOSITORY/branches/development/protection --method PUT \ + -f required_status_checks[0].context='test-release-candidate' \ + -f enforce_admins=true \ + -f required_pull_request_reviews[0].required_approving_review_count=1 + + gh api repos/$GITHUB_REPOSITORY/branches/main/protection --method PUT \ + -f required_status_checks[0].context='test-release-candidate' \ + -f enforce_admins=true \ + -f required_pull_request_reviews[0].required_approving_review_count=1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release_flow.yml b/.github/workflows/release_flow.yml new file mode 100644 index 00000000..ea07e997 --- /dev/null +++ b/.github/workflows/release_flow.yml @@ -0,0 +1,96 @@ +name: Release Flow Management + +on: + push: + branches: + - development + - 'rc/*' + - main + pull_request: + types: [closed] + branches: + - development + - 'rc/*' + - main + +jobs: + manage-release-flow: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Git + run: | + git config user.name "GitHub Actions" + git config user.email "actions@github.com" + + # Create Release Candidate from Development + - name: Create RC Branch + if: | + github.event_name == 'push' && + github.ref == 'refs/heads/development' && + !contains(github.event.head_commit.message, 'chore(deps)') + run: | + RC_VERSION=$(date +%Y%m%d)-$(git rev-parse --short HEAD) + git checkout -b rc/$RC_VERSION development + git push origin rc/$RC_VERSION + gh pr create \ + --title "Release Candidate $RC_VERSION" \ + --body "Automated release candidate from development branch" \ + --base main \ + --head rc/$RC_VERSION \ + --label "release-candidate" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Merge to Main and Create Release + - name: Create Release + if: | + github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + startsWith(github.event.pull_request.head.ref, 'rc/') && + github.event.pull_request.base.ref == 'main' + run: | + VERSION=$(echo ${{ github.event.pull_request.head.ref }} | sed 's/rc\///') + git tag -a v$VERSION -m "Release v$VERSION" + git push origin v$VERSION + gh release create v$VERSION \ + --title "Release v$VERSION" \ + --notes "Release candidate merged to main" \ + --target main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Sync Main back to Development + - name: Sync Development + if: | + github.event_name == 'push' && + github.ref == 'refs/heads/main' + run: | + git checkout development + git merge --no-ff main + git push origin development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Automated Tests for Release Candidates + test-release-candidate: + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/heads/rc/') + steps: + - uses: actions/checkout@v3 + + - name: Setup Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + + - name: Run Tests + run: cargo test --all-features --verbose + + - name: Run Security Audit + run: | + cargo install cargo-audit + cargo audit diff --git a/scripts/standardize_repos.sh b/scripts/standardize_repos.sh new file mode 100644 index 00000000..e154701c --- /dev/null +++ b/scripts/standardize_repos.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Configuration +ORG_NAME="anya" # Replace with your organization name +GITHUB_TOKEN="${GITHUB_TOKEN}" # Set this in your environment +GPG_KEY="6116504FE0507099" +GIT_NAME="bo_thebig" +GIT_EMAIL="botshelomokoka@gmail.com" + +# Required files to copy to all repos +WORKFLOW_FILES=( + ".github/workflows/release_flow.yml" + ".github/workflows/branch_maintenance.yml" + ".github/dependabot.yml" +) + +# Get all repositories +echo "Fetching repositories..." +repos=$(gh repo list $ORG_NAME --json nameWithOwner --jq '.[].nameWithOwner') + +for repo in $repos; do + echo "Processing repository: $repo" + + # Clone repository + git clone "https://github.com/$repo.git" temp_repo + cd temp_repo + + # Setup git config with GPG + git config user.name "$GIT_NAME" + git config user.email "$GIT_EMAIL" + git config user.signingkey "$GPG_KEY" + git config commit.gpgsign true + + # Create development branch if it doesn't exist + if ! git show-ref --verify --quiet refs/remotes/origin/development; then + echo "Creating development branch for $repo" + git checkout -b development main || git checkout -b development master + git push origin development + fi + + # Copy workflow files + mkdir -p .github/workflows + for file in "${WORKFLOW_FILES[@]}"; do + cp "../$file" "./$file" 2>/dev/null || echo "Warning: Could not copy $file" + done + + # Commit changes if any + if git status --porcelain | grep -q '^'; then + git add . + git commit -m "chore: standardize repository structure and workflows" + git push origin development + fi + + # Analyze and clean branches + echo "Analyzing branches for $repo" + + # List merged branches + merged_branches=$(git branch --merged development | grep -v "^\*" | grep -vE "^(\s*development|\s*main|\s*master)$") + + # List stale branches (no commits in 30 days) + stale_branches=$(git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)|%(committerdate:iso8601)' | + while IFS='|' read -r branch date; do + if [[ ! "$branch" =~ ^(main|development|master)$ ]] && [[ $(date -d "$date" +%s) -lt $(date -d "30 days ago" +%s) ]]; then + echo "$branch" + fi + done) + + # Generate report + echo "# Branch Cleanup Report for $repo" > "../reports/${repo//\//_}_report.md" + echo "## Merged Branches" >> "../reports/${repo//\//_}_report.md" + echo "$merged_branches" >> "../reports/${repo//\//_}_report.md" + echo "## Stale Branches" >> "../reports/${repo//\//_}_report.md" + echo "$stale_branches" >> "../reports/${repo//\//_}_report.md" + + # Create issue with report + gh issue create \ + --repo "$repo" \ + --title "Branch Cleanup Required" \ + --body-file "../reports/${repo//\//_}_report.md" \ + --label "maintenance,branch-cleanup" + + cd .. + rm -rf temp_repo +done + +echo "Repository standardization complete!"