"""GitHub Actions integration for README auto-update workflows.""" from pathlib import Path from typing import Optional from ..models import Project class GitHubActionsGenerator: """Generates GitHub Actions workflows for README updates.""" WORKFLOW_TEMPLATE = """name: Auto Update README on: push: branches: [main, master] paths: - '**.py' - '**.js' - '**.ts' - '**.go' - '**.rs' - 'package.json' - 'pyproject.toml' - 'go.mod' - 'Cargo.toml' - 'requirements.txt' workflow_dispatch: inputs: force: description: 'Force README regeneration' required: false default: 'false' jobs: update-readme: runs-on: ubuntu-latest if: github.repository_owner != '{{ owner }}' || github.event_name == 'workflow_dispatch' steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install auto-readme run: | pip install --upgrade pip pip install auto-readme-cli - name: Generate README run: | auto-readme generate --input . --output README.md --force - name: Commit and push changes if: github.event_name != 'workflow_dispatch' || github.event.inputs.force == 'true' run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add README.md git diff --quiet README.md || git commit -m "docs: Auto-update README" git push env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} """ @classmethod def can_generate(cls, project: Project) -> bool: """Check if GitHub Actions integration can be generated.""" return ( project.git_info is not None and project.git_info.is_repo and project.git_info.owner is not None ) @classmethod def generate_workflow(cls, project: Project, output_path: Optional[Path] = None) -> str: """Generate the GitHub Actions workflow content.""" owner = project.git_info.owner if project.git_info else "owner" workflow_content = cls.WORKFLOW_TEMPLATE.replace("{{ owner }}", owner) return workflow_content @classmethod def save_workflow(cls, project: Project, output_dir: Path) -> Path: """Save the GitHub Actions workflow to a file.""" workflow_content = cls.generate_workflow(project) workflow_path = output_dir / ".github" / "workflows" / "readme-update.yml" workflow_path.parent.mkdir(parents=True, exist_ok=True) workflow_path.write_text(workflow_content) return workflow_path class GitHubRepoDetector: """Detects GitHub repository information.""" @staticmethod def is_github_repo(remote_url: Optional[str]) -> bool: """Check if the remote URL is a GitHub repository.""" if not remote_url: return False return "github.com" in remote_url.lower() @staticmethod def extract_repo_info(remote_url: Optional[str]) -> tuple[Optional[str], Optional[str]]: """Extract owner and repo name from remote URL.""" if not remote_url: return None, None import re patterns = [ r"github\.com[:/]([^/]+)/([^/]+)\.git", r"github\.com/([^/]+)/([^/]+)", r"git@github\.com:([^/]+)/([^/]+)\.git", r"git@github\.com:([^/]+)/([^/]+)", ] for pattern in patterns: match = re.search(pattern, remote_url) if match: owner, repo = match.groups() repo = repo.replace(".git", "") return owner, repo return None, None