{"id":25841660,"url":"https://github.com/somaz94/commit-info-extractor","last_synced_at":"2026-04-03T11:01:31.632Z","repository":{"id":242461021,"uuid":"809549897","full_name":"somaz94/commit-info-extractor","owner":"somaz94","description":"commit-info-extractor","archived":false,"fork":false,"pushed_at":"2026-03-26T07:22:53.000Z","size":213,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-27T02:12:57.492Z","etag":null,"topics":["automation","changelog","ci-cd","devops","git-commit","git-log","github-action","github-actions","release"],"latest_commit_sha":null,"homepage":"https://github.com/marketplace/actions/extract-commit-action","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/somaz94.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-03T01:37:24.000Z","updated_at":"2026-03-26T07:22:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"0c7def89-6571-4ca9-a908-2c80b670d71f","html_url":"https://github.com/somaz94/commit-info-extractor","commit_stats":null,"previous_names":["somaz94/commit-info-extractor"],"tags_count":14,"template":false,"template_full_name":"actions/container-action","purl":"pkg:github/somaz94/commit-info-extractor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somaz94%2Fcommit-info-extractor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somaz94%2Fcommit-info-extractor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somaz94%2Fcommit-info-extractor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somaz94%2Fcommit-info-extractor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/somaz94","download_url":"https://codeload.github.com/somaz94/commit-info-extractor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somaz94%2Fcommit-info-extractor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31347183,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T08:03:20.796Z","status":"ssl_error","status_checked_at":"2026-04-03T08:00:37.834Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","changelog","ci-cd","devops","git-commit","git-log","github-action","github-actions","release"],"created_at":"2025-03-01T05:29:57.735Z","updated_at":"2026-04-03T11:01:31.627Z","avatar_url":"https://github.com/somaz94.png","language":"Python","readme":"# Extract Commit Action\n\n![CI](https://github.com/somaz94/commit-info-extractor/actions/workflows/ci.yml/badge.svg)\n[![License](https://img.shields.io/github/license/somaz94/commit-info-extractor)](https://github.com/somaz94/commit-info-extractor/blob/main/LICENSE)\n![Latest Tag](https://img.shields.io/github/v/tag/somaz94/commit-info-extractor)\n![Python](https://img.shields.io/badge/python-3.14-blue?logo=python)\n[![GitHub Marketplace](https://img.shields.io/badge/Marketplace-Commit%20Info%20Extractor-blue?logo=github)](https://github.com/marketplace/actions/extract-commit-action)\n\nA powerful GitHub Action that extracts and processes information from commit messages using customizable patterns and commands.\n\n\u003cbr/\u003e\n\n## Features\n\n- **Flexible Pattern Matching**: Extract information using regex patterns or custom commands\n- **Multiple Output Formats**: Support for text, JSON, and CSV outputs\n- **Customizable Depth**: Control the number of commits to analyze\n- **Fast \u0026 Lightweight**: Built with Python 3.14-slim for optimal performance\n- **Fail-Safe Options**: Optional validation with `fail_on_empty`\n- **Pretty Formatting**: Clean, formatted commit message output\n- **Debug Mode**: Verbose output for troubleshooting\n- **Timeout Control**: Prevent long-running operations\n- **Easy Integration**: Simple YAML configuration in your workflows\n\u003cbr/\u003e\n\n## Quick Start\n\n```yaml\n- name: Extract Environment from Commits\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'env:(\\\\w+)'\"\n    pretty: true\n    key_variable: 'DEPLOY_ENV'\n```\n\n\u003cbr/\u003e\n\n## Inputs\n\n| Input | Description | Required | Default |\n|-------|-------------|----------|---------|\n| `commit_limit` | Number of commits to retrieve | Yes | N/A |\n| `extract_command` | Command to extract info (e.g., grep pattern) | No | N/A |\n| `extract_pattern` | Regex pattern to extract info (safer alternative to `extract_command`) | No | N/A |\n| `commit_range` | Git commit range (e.g., `HEAD~5..HEAD`, `v1.0.0..v1.1.0`) | No | N/A |\n| `pretty` | Use pretty format for Git logs | No | `false` |\n| `key_variable` | Name of the output variable | No | `ENVIRONMENT` |\n| `fail_on_empty` | Fail if no information is extracted | No | `false` |\n| `output_format` | Output format: `text`, `json`, or `csv` | No | `text` |\n| `debug` | Enable debug mode for verbose output | No | `false` |\n| `timeout` | Timeout in seconds for git/extract commands | No | `30` |\n\n\u003e **Note**: `extract_command` and `extract_pattern` are mutually exclusive. Use `extract_pattern` for safer regex matching without shell execution.\n\n\u003cbr/\u003e\n\n## Outputs\n\n| Output | Description |\n|--------|-------------|\n| `key_variable` | The name of the variable used |\n| `value_variable` | The extracted value(s) from commits |\n| `match_count` | Number of extracted matches |\n\n\u003cbr/\u003e\n\n## Common Use Cases\n\n\u003cbr/\u003e\n\n### Extract Environment Information\n\n```yaml\n- name: Extract Environment\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'env:(\\\\w+)'\"\n    pretty: true\n    key_variable: 'DEPLOY_ENV'\n```\n\n\u003cbr/\u003e\n\n### Find Feature Tags\n\n```yaml\n- name: Extract Feature Tags\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'feature:(\\\\w+)'\"\n    key_variable: 'FEATURE_TAG'\n```\n\n\u003cbr/\u003e\n\n### Extract Version Numbers\n\n```yaml\n- name: Extract Version\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'v[0-9]+\\\\.[0-9]+\\\\.[0-9]+'\"\n    key_variable: 'VERSION'\n```\n\n\u003cbr/\u003e\n\n### Fail on Empty Results\n\n```yaml\n- name: Extract Critical Changes\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'critical:(\\\\w+)'\"\n    key_variable: 'CRITICAL_CHANGES'\n    fail_on_empty: true  # Fails if no matches found\n```\n\n\u003cbr/\u003e\n\n### Extract JIRA Tickets with JSON Output\n\n```yaml\n- name: Extract JIRA Tickets\n  id: jira\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 20\n    extract_command: \"grep -oE 'JIRA-[0-9]+'\"\n    key_variable: 'JIRA_TICKETS'\n    output_format: 'json'\n\n- name: Process Tickets\n  run: |\n    echo '${{ steps.jira.outputs.value_variable }}' | jq -r '.[]'\n```\n\n\u003cbr/\u003e\n\n### Extract Using Regex Pattern (Safe)\n\n```yaml\n- name: Extract JIRA Tickets (Pattern)\n  id: jira_pattern\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_pattern: 'JIRA-[0-9]+'\n    key_variable: 'JIRA_TICKETS'\n\n- name: Check Match Count\n  run: |\n    echo \"Found ${{ steps.jira_pattern.outputs.match_count }} tickets\"\n    echo \"Tickets: ${{ steps.jira_pattern.outputs.value_variable }}\"\n```\n\n\u003cbr/\u003e\n\n### Extract from Commit Range\n\n```yaml\n- name: Extract Changes Between Tags\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    commit_range: 'v1.0.0..v1.1.0'\n    extract_pattern: '(feat|fix|chore):'\n    key_variable: 'CHANGE_TYPES'\n\n- name: Extract Recent Changes\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    commit_range: 'HEAD~5..HEAD'\n    extract_pattern: 'env:(\\w+)'\n    key_variable: 'DEPLOY_ENV'\n```\n\n\u003cbr/\u003e\n\n### Debug Mode for Troubleshooting\n\n```yaml\n- name: Extract with Debug\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'env:(\\\\w+)'\"\n    key_variable: 'ENVIRONMENT'\n    debug: true          # Enable verbose output\n    timeout: 60          # Set custom timeout\n```\n\n\u003cbr/\u003e\n\n## Output Formats\n\nThe action supports three output formats:\n\n| Format | Description | Example Output |\n|--------|-------------|----------------|\n| `text` | Plain text (default) | `value1`\u003cbr/\u003e`value2`\u003cbr/\u003e`value3` |\n| `json` | JSON array | `[\"value1\", \"value2\", \"value3\"]` |\n| `csv` | Comma-separated | `value1,value2,value3` |\n\n\u003cbr/\u003e\n\n### Format Examples\n\nGiven extracted values: `JIRA-123`, `JIRA-456`, `JIRA-789`\n\n#### Text format:\n```\nJIRA-123\nJIRA-456\nJIRA-789\n```\n\n#### JSON format:\n```json\n[\"JIRA-123\", \"JIRA-456\", \"JIRA-789\"]\n```\n\n#### CSV format:\n```\nJIRA-123,JIRA-456,JIRA-789\n```\n\n\u003cbr/\u003e\n\n## Extract Command Examples\n\n| Purpose | Command | Example Match |\n|---------|---------|---------------|\n| Environment | `grep -oE 'env:(\\\\w+)'` | `env:production` |\n| Fix IDs | `grep -oE 'fix-[0-9]+'` | `fix-123` |\n| Versions | `grep -oE 'v[0-9]+\\\\.[0-9]+\\\\.[0-9]+'` | `v1.2.3` |\n| Features | `grep -oE 'feature:(\\\\w+)'` | `feature:login` |\n| JIRA IDs | `grep -oE 'JIRA-[0-9]+'` | `JIRA-456` |\n| Conventional Commits | `grep -oE '^(feat|fix|chore|docs):'` | `feat:`, `fix:` |\n\n\u003e **Note**: Use `grep -oE` (Extended regex) instead of `grep -oP` (Perl regex) for better compatibility.\n\n\u003cbr/\u003e\n\n## Extract Pattern Examples\n\n`extract_pattern` uses Python's `re` module for safe regex matching without shell execution.\n\n| Purpose | Pattern | Example Match |\n|---------|---------|---------------|\n| Environment | `env:(\\w+)` | `production` (captured group) |\n| JIRA IDs | `JIRA-[0-9]+` | `JIRA-456` |\n| Versions | `v\\d+\\.\\d+\\.\\d+` | `v1.2.3` |\n| Conventional Commits | `(feat\\|fix\\|chore\\|docs):` | `feat:`, `fix:` |\n| PR Numbers | `#(\\d+)` | `123` (captured group) |\n\n\u003e **Note**: When using capture groups `()`, only the captured portion is returned. Without groups, the full match is returned.\n\n\u003cbr/\u003e\n\n## Best Practices\n\n\u003cbr/\u003e\n\n### Commit Message Format\n- Use consistent commit message formats (e.g., [Conventional Commits](https://www.conventionalcommits.org/))\n- Include relevant tags or identifiers\n- Example: `feat(auth): add login functionality env:production`\n\n\u003cbr/\u003e\n\n### Extraction Patterns\n- Test regex patterns locally before implementation:\n  ```bash\n  echo \"feat: add login env:production\" | grep -oE 'env:(\\\\w+)'\n  ```\n- Use specific patterns to avoid false matches\n- Consider edge cases and special characters\n\n\u003cbr/\u003e\n\n### Performance\n- Set appropriate `commit_limit` based on your needs\n- Lower values = faster execution\n- Typical range: 10-50 commits\n\n\u003cbr/\u003e\n\n### Repository Setup\n- Ensure sufficient `fetch-depth` in checkout action:\n  ```yaml\n  - uses: actions/checkout@v6\n    with:\n      fetch-depth: 20  # Match or exceed commit_limit\n  ```\n\n\u003cbr/\u003e\n\n## Troubleshooting\n\n\u003cbr/\u003e\n\n### No Matches Found\n\n#### Problem: Action completes but returns empty results\n\n#### Solutions:\n1. Verify commit messages contain expected patterns:\n   ```bash\n   git log -10 --pretty=%B\n   ```\n2. Test your regex pattern locally:\n   ```bash\n   git log -10 --pretty=%B | grep -oE 'your-pattern'\n   ```\n3. Ensure `fetch-depth` in checkout is sufficient\n4. Check if `fail_on_empty` is set appropriately\n\n\u003cbr/\u003e\n\n### Incorrect Matches\n\n#### Problem: Extracting wrong or unexpected values\n\n#### Solutions:\n- Review and refine your regex pattern\n- Use more specific patterns with word boundaries\n- Test with sample commit messages first\n- Use online regex testers like [regex101.com](https://regex101.com)\n\n\u003cbr/\u003e\n\n### Action Fails with Error\n\n#### Problem: Action exits with non-zero code\n\n#### Possible Causes:\n- `fail_on_empty: true` is set and no matches found (intended behavior)\n- Invalid regex pattern in `extract_command`\n- Git repository not available\n- Insufficient permissions\n\n#### Debug Steps:\n```yaml\n- name: Debug Commit Messages\n  run: git log -${{ inputs.commit_limit }} --pretty=%B\n\n- name: Test Extract Command\n  run: |\n    git log -10 --pretty=%B | grep -oE 'your-pattern' || echo \"No matches\"\n\n# Or use built-in debug mode\n- name: Extract with Debug Mode\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'your-pattern'\"\n    debug: true  # Shows detailed execution information\n```\n\n\u003cbr/\u003e\n\n### Timeout Errors\n\n#### Problem: Action times out during execution\n\n#### Solutions:\n- Increase timeout value (default is 30 seconds):\n  ```yaml\n  - uses: somaz94/commit-info-extractor@v1\n    with:\n      commit_limit: 10\n      extract_command: \"complex-command\"\n      timeout: 120  # Increase to 2 minutes\n  ```\n- Reduce `commit_limit` to process fewer commits\n- Simplify your `extract_command` pattern\n\n\u003cbr/\u003e\n\n## Advanced Usage\n\n\u003cbr/\u003e\n\n### Processing Multiple Matches\n\nWhen multiple values are extracted, you can process them in subsequent steps:\n\n#### Text format:\n```yaml\n- name: Extract JIRA Tickets\n  id: extract\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'JIRA-[0-9]+'\"\n    key_variable: 'JIRA_TICKETS'\n\n- name: Process Each Ticket\n  run: |\n    while IFS= read -r ticket; do\n      echo \"Processing: $ticket\"\n      # Your processing logic here\n    done \u003c\u003c\u003c \"${{ steps.extract.outputs.value_variable }}\"\n```\n\n#### JSON format:\n```yaml\n- name: Extract as JSON\n  id: extract_json\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 10\n    extract_command: \"grep -oE 'JIRA-[0-9]+'\"\n    output_format: 'json'\n\n- name: Process JSON Array\n  run: |\n    echo '${{ steps.extract_json.outputs.value_variable }}' | \\\n      jq -r '.[]' | while read -r ticket; do\n        echo \"Processing: $ticket\"\n      done\n```\n\n\u003cbr/\u003e\n\n### Combining with Other Actions\n\n#### Send to Slack:\n```yaml\n- name: Extract Deployment Info\n  id: deploy\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 5\n    extract_command: \"grep -oE 'env:(\\\\w+)'\"\n    key_variable: 'ENVIRONMENT'\n\n- name: Notify Slack\n  uses: slackapi/slack-github-action@v1\n  with:\n    payload: |\n      {\n        \"text\": \"Deploying to: ${{ steps.deploy.outputs.value_variable }}\"\n      }\n```\n\n#### Conditional Deployment:\n```yaml\n- name: Check for Production Tag\n  id: check_env\n  uses: somaz94/commit-info-extractor@v1\n  with:\n    commit_limit: 1\n    extract_command: \"grep -oE 'env:production'\"\n    fail_on_empty: false\n\n- name: Deploy to Production\n  if: steps.check_env.outputs.value_variable == 'env:production'\n  run: |\n    echo \"Deploying to production...\"\n```\n\n\u003cbr/\u003e\n\n## Security Considerations\n\nWhen using this action, keep the following in mind:\n\n#### Command Injection Prevention\n- The `extract_command` executes shell commands — never use untrusted user input\n- Prefer `extract_pattern` over `extract_command` for safer regex matching (no shell execution)\n- Always validate and sanitize inputs\n\n#### Sensitive Information\n- Be careful not to extract secrets or credentials from commit messages\n- Use GitHub's [secret scanning](https://docs.github.com/en/code-security/secret-scanning) alongside this action\n- Consider filtering sensitive patterns\n\n#### Permission Scopes\n- This action only requires **read access** to repository content\n- Follow the principle of least privilege in your workflows\n\n\u003cbr/\u003e\n\n## Project Structure\n\n```\nentrypoint.py              # Thin wrapper (calls app.main.run)\napp/\n  main.py                  # Orchestration entrypoint\n  config.py                # AppConfig dataclass (from_env, validate)\n  git_client.py            # Git operations (configure, fetch commits)\n  extractor.py             # Extraction logic (command \u0026 regex pattern)\n  formatter.py             # Output formatting (text/json/csv)\n  output_writer.py         # GITHUB_ENV/GITHUB_OUTPUT writing\n  logger.py                # Logging utilities\ntests/\n  conftest.py              # pytest fixtures\n  test_config.py           # Config unit tests\n  test_extractor.py        # Extraction logic tests\n  test_formatter.py        # Formatter tests\n  test_git_client.py       # Git client tests\n  test_output_writer.py    # Output writer tests\n  test_main.py             # Integration tests (mocked)\n  test_local.py            # Local integration test\n```\n\n\u003cbr/\u003e\n\n## Local Testing\n\n```bash\n# Clone the repository\ngit clone https://github.com/somaz94/commit-info-extractor.git\ncd commit-info-extractor\n\n# Using Makefile (recommended)\nmake venv          # Create virtualenv and install dev dependencies\nmake test          # Run unit tests with coverage\nmake test-local    # Run local integration test\nmake coverage      # Generate HTML coverage report\nmake clean         # Remove venv, cache, and build artifacts\nmake help          # Show all available commands\n\n# Or manually\npython -m venv venv \u0026\u0026 source venv/bin/activate\npip install -r requirements-dev.txt\npython -m pytest tests/ -v --cov=app --cov-report=term-missing\n```\n\nSee [tests/TESTING.md](tests/TESTING.md) for more details.\n\n\u003cbr/\u003e\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for version history and updates.\n\n\u003cbr/\u003e\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n\u003cbr/\u003e\n\n## Contributing\n\nContributions are welcome! Please feel free to:\n- Report bugs\n- Suggest new features\n- Submit pull requests\n- Improve documentation\n\n\u003cbr/\u003e\n\n## Support\n\nIf you find this action helpful, please consider:\n- Starring the repository\n- Sharing with others\n- Contributing improvements\n\n\u003cbr/\u003e\n\n## Related Projects\n\n- [actions/checkout](https://github.com/actions/checkout) - Checkout your repository\n- [github-script](https://github.com/actions/github-script) - Write workflows using JavaScript\n- [setup-python](https://github.com/actions/setup-python) - Set up Python environment\n\n---\n\nMade by [somaz94](https://github.com/somaz94)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsomaz94%2Fcommit-info-extractor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsomaz94%2Fcommit-info-extractor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsomaz94%2Fcommit-info-extractor/lists"}