{"id":50664876,"url":"https://github.com/esteve/release-ros-robot","last_synced_at":"2026-06-08T05:30:26.683Z","repository":{"id":334069254,"uuid":"1139930805","full_name":"esteve/release-ros-robot","owner":"esteve","description":"A GitHub action that releases ROS packages via bloom-release in a release-please workflow","archived":false,"fork":false,"pushed_at":"2026-04-25T16:33:16.000Z","size":397,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T17:29:26.591Z","etag":null,"topics":["bloom","ros","ros2"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esteve.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"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":"2026-01-22T15:52:54.000Z","updated_at":"2026-04-25T17:13:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/esteve/release-ros-robot","commit_stats":null,"previous_names":["esteve/release-ros-bot","esteve/release-ros-robot"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/esteve/release-ros-robot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esteve%2Frelease-ros-robot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esteve%2Frelease-ros-robot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esteve%2Frelease-ros-robot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esteve%2Frelease-ros-robot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esteve","download_url":"https://codeload.github.com/esteve/release-ros-robot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esteve%2Frelease-ros-robot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34050225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["bloom","ros","ros2"],"created_at":"2026-06-08T05:30:25.912Z","updated_at":"2026-06-08T05:30:26.662Z","avatar_url":"https://github.com/esteve.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Release ROS Robot\n\nA GitHub Action to automate ROS package releases using `bloom-release`. It follows a workflow similar to [release-please](https://github.com/googleapis/release-please) and [release-plz](https://release-plz.dev/), but for ROS packages.\n\n## Features\n\n- Automated Release PRs: Creates PRs with changelog and version bumps, like release-please and release-plz\n- Conventional Commits: Auto-detects version bump type from commit messages\n- Automatic changelog generation in catkin CHANGELOG.rst format\n- Automatic version bumping in package.xml files\n- Multi-distro support via explicit workflow inputs\n- Automatic PR creation to [rosdistro](https://github.com/ros/rosdistro)\n- Support for both first-time and subsequent releases\n\n## Quick Start\n\nUsers familiar with [release-please](https://github.com/googleapis/release-please) or [release-plz](https://release-plz.dev/) will recognize the same PR-driven release workflow. Consumers only need a workflow file, no configuration files in the repository.\n\n1. When you merge PRs to `main`, the action creates/updates a release PR with changelog and version bump\n2. When you merge the release PR, the action automatically runs `bloom-release` for configured ROS distros\n\n### 1. Create the GitHub workflow\n\nCreate `.github/workflows/bloom-release.yaml`:\n\n```yaml\nname: Release\n\non:\n  push:\n    branches:\n      - main\n      - jazzy\n      - humble\n\njobs:\n  # Runs on every push. Self-skips on non-release commits.\n  release:\n    name: Release\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    env:\n      BLOOM_OAUTH_TOKEN: ${{ secrets.BLOOM_OAUTH_TOKEN }}\n      BLOOM_GITHUB_USER: ${{ secrets.BLOOM_GITHUB_USER }}\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n          persist-credentials: false\n\n      - name: Run bloom-release (main → rolling)\n        if: github.ref_name == 'main'\n        uses: esteve/release-ros-robot@v0\n        with:\n          mode: release\n          repository: my_ros_package\n          rosdistro: rolling\n          track: rolling\n          release-repository: https://github.com/ros2-gbp/my_ros_package-release.git\n\n      - name: Run bloom-release (jazzy)\n        if: github.ref_name == 'jazzy'\n        uses: esteve/release-ros-robot@v0\n        with:\n          mode: release\n          repository: my_ros_package\n          rosdistro: jazzy\n          track: jazzy\n          release-repository: https://github.com/ros2-gbp/my_ros_package-release.git\n\n      - name: Run bloom-release (humble)\n        if: github.ref_name == 'humble'\n        uses: esteve/release-ros-robot@v0\n        with:\n          mode: release\n          repository: my_ros_package\n          rosdistro: humble\n          track: humble\n          release-repository: https://github.com/ros2-gbp/my_ros_package-release.git\n\n  # Runs on every push. Self-skips when the push came from merging a release PR.\n  # The concurrency block ensures only one instance runs at a time per branch.\n  release-pr:\n    name: Release PR\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n    concurrency:\n      group: release-pr-${{ github.ref }}\n      cancel-in-progress: false\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n          persist-credentials: false\n\n      - name: Update release PR\n        uses: esteve/release-ros-robot@v0\n        with:\n          mode: prepare\n          base-branch: ${{ github.ref_name }}\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\nKeep release runs sequential when multiple tracks share the same release\nrepository. The example above is sequential because each release happens in a\nseparate step; if you switch to a matrix, set `strategy.max-parallel: 1`.\n\n\u003e Running in forks? Add `if: ${{ github.repository_owner == 'YOUR_ORG' }}` to\n\u003e each job to prevent the workflow from running (and failing) in forks. This is\n\u003e the same pattern recommended by the\n\u003e [release-plz quickstart](https://release-plz.dev/docs/github/quickstart).\n\n### 2. Set up secrets\n\n`BLOOM_OAUTH_TOKEN` and `BLOOM_GITHUB_USER` are only needed by the\n`release` job (Settings → Secrets and variables → Actions):\n\n`BLOOM_OAUTH_TOKEN`, A GitHub Personal Access Token (PAT) with:\n- `public_repo`. For creating PRs on rosdistro\n- `workflow`. For pushing tags and commits\n\n`BLOOM_GITHUB_USER`, The GitHub username that owns the PAT above.\nbloom-release uses a fork-based workflow: it pushes rosdistro changes to\n`\u003cBLOOM_GITHUB_USER\u003e/rosdistro` before opening a PR to `ros/rosdistro`.\nThe action ensures this fork exists before running bloom. On the first release,\nit may create `\u003cBLOOM_GITHUB_USER\u003e/rosdistro` automatically.\n\nThe `release-pr` job uses the built-in `GITHUB_TOKEN`, no extra secrets needed.\n\n### 3. Use Conventional Commits\n\nThe action automatically detects version bump type from your commit messages\nusing the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification:\n\n```bash\nfeat: add new feature         # -\u003e minor bump\nfix: correct bug              # -\u003e patch bump\nfeat!: breaking change        # -\u003e major bump\nfix: bug fix\n\nBREAKING CHANGE: description  # -\u003e major bump\n```\n\n## How It Works\n\n### Prepare Mode\n\n1. Analyzes commits since last tag using Conventional Commits\n2. Determines version bump type (major/minor/patch)\n3. Updates `package.xml` with new version\n4. Generates/updates `CHANGELOG.rst` files following REP-0132:\n   - Version header with date\n   - Commit bullet list sorted by significance (breaking first, then features, fixes, other)\n   - Contributor attribution\n5. Creates or force-pushes to release PR branch: `bloom-release-\u003ctimestamp\u003e`\n\n### Release Mode\n\nTriggered by the push that merging the release PR creates. The merge commit\nmessage starts with `chore(release):`, which the `release` job detects to\ndecide whether to proceed. On any other push the job exits immediately.\n\n1. Reads version from `package.xml` (already updated by prepare mode)\n2. Creates git tag with version number (idempotent. Skips if tag already exists)\n3. Ensures the PAT owner's `rosdistro` fork exists\n4. Runs `bloom-release` with the explicitly provided repository, distribution,\n   track, and release repository\n5. Creates PR(s) to ros/rosdistro\n\nBecause the no-op guard is commit-driven rather than tag-driven, multiple\nrelease steps targeting different tracks on the same branch can all operate on\nthe same release commit. The source tag is only created once, but bloom still\nmutates shared state in the release repository, so releases for a shared\nrelease repository should run sequentially. If you use a matrix, set\n`strategy.max-parallel: 1`.\n\n### Multi-Package Repositories\n\nThis action supports repositories with multiple ROS packages (e.g.,\n[rclcpp](https://github.com/ros2/rclcpp), [ros2_control](https://github.com/ros-controls/ros2_control)). Per bloom's\nrequirements:\n\n- Synchronized versions. All `package.xml` files must share the same\n  version. The action enforces this and fails with a clear error if they\n  drift. Version bumps are applied to every `package.xml` at once, and a\n  single git tag is created per release.\n\n- Per-package changelogs. Each package gets its own `CHANGELOG.rst`.\n  All entries share the same version header and date, but bullet points\n  are filtered so each package's changelog only lists commits that touched\n  files inside that package's directory. This matches the ROS convention\n  used by [rclcpp](https://github.com/ros2/rclcpp) and similar monorepos.\n\n- Packages with no changes. Still get a version header (with an empty\n  body) in their `CHANGELOG.rst`, since bloom releases all packages at the\n  same version.\n\n- Repo-wide commits. Commits that don't touch any package directory\n  (e.g., root `README.md`, CI config, `.github/` changes) are not included\n  in any package's changelog.\n\n### Excluding Test Fixtures and Vendored Code\n\nIf your repository contains `package.xml` files that should not be\ntreated as real packages (e.g., test fixtures, vendored third-party code),\nuse the `exclude-paths` input:\n\n```yaml\n      - name: Update release PR\n        uses: esteve/release-ros-robot@v0\n        with:\n          mode: prepare\n          base-branch: ${{ github.ref_name }}\n          exclude-paths: |\n            test/**\n            tests/**\n            third_party/**\n            vendor/**\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\nAdd the same `exclude-paths` input to the `release` steps as well.\n\nPatterns are POSIX-style globs matched against the full relative path of\neach `package.xml` (e.g., `test/fixtures/minimal/package.xml`). Without\nthis exclusion, fixture `package.xml` files would be:\n\n1. Checked against the version consistency requirement. Usually causing\n   release failure with a version mismatch error\n2. Rewritten in place with the new release version\n3. Given a spurious `CHANGELOG.rst` in the fixture directory\n4. Staged for commit in the release PR\n\n## Action Inputs\n\n| Input | Description | Required | Default |\n|-------|-------------|----------|---------|\n| `mode` | Action mode: `prepare` or `release` | No | `release` |\n| `oauth-token` | PAT for release mode. Falls back to `BLOOM_OAUTH_TOKEN` env var. Not used in prepare mode. | No | - |\n| `github-user` | GitHub username for bloom fork workflow. Falls back to `BLOOM_GITHUB_USER` env var. Release mode only. | No | - |\n| `repository` | Repository name as registered in rosdistro. Required in release mode. | No | - |\n| `rosdistro` | ROS distribution to release (e.g., `rolling`, `jazzy`). Required in release mode. | No | - |\n| `track` | Bloom track to use (e.g., `rolling`, `jazzy`). Required in release mode. | No | - |\n| `release-repository` | Release repository URL (e.g., `https://github.com/ros2-gbp/my_package-release.git`). Required in release mode. | No | - |\n| `dry-run` | Run without actually releasing | No | `false` |\n| `exclude-paths` | Newline-separated glob patterns to exclude from `package.xml` discovery | No | - |\n| `version-bump` | Version bump type: `auto`, `patch`, `minor`, `major` | No | `auto` |\n| `base-branch` | Base branch for release PR | No | `main` |\n\n## Action Outputs\n\n| Output | Description |\n|--------|-------------|\n| `pr-created` | Whether a release PR was created (`prepare` mode) |\n| `released` | Whether a release was performed (`release` mode) |\n| `version` | The version that was released or will be released |\n| `rosdistro` | The ROS distribution released to (`release` mode) |\n| `pr-url` | URL of the release PR or rosdistro PR |\n\n\n## Conventional Commits\n\nThe action supports automatic version bump detection using the\n[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification:\n\n```\n\u003ctype\u003e[optional scope][!]: \u003cdescription\u003e\n```\n\nVersion bump rules:\n- `BREAKING CHANGE` in message or `!` after type → `major`\n- `feat` type → `minor`\n- `fix`, `perf`, `refactor`, `docs`, `style`, `test`, `chore`, `build`, `ci` → `patch`\n\nExamples:\n```\nfeat: add new ROS distro support          → minor\nfeat!: redesign configuration format      → major\nfix: correct version parsing              → patch\ndocs: update README                       → patch\nrefactor(core): simplify release logic    → patch\n```\n\nSet `version-bump: auto` (default) to enable automatic detection.\n\n## Prerequisites\n\n### Repository Workflow Permissions\n\nGo to your repository Settings -\u003e Actions -\u003e General -\u003e Workflow permissions:\n\n1. Select \"Read and write permissions\"\n2. Check \"Allow GitHub Actions to create and approve pull requests\"\n\nThis is required by the `release-pr` job so that `GITHUB_TOKEN` can push the\nrelease branch and open a PR in your repository.\n\n### Token Permissions\n\n`release-pr` job uses `GITHUB_TOKEN` (automatic -- no extra setup needed) with:\n- `contents: write` -- push the release branch\n- `pull-requests: write` -- create/update the release PR\n\n`release` job uses `BLOOM_OAUTH_TOKEN` (PAT you create) with:\n- `public_repo` -- open a PR on `ros/rosdistro`\n- `workflow` -- push tags and commits to your repository\n\n## Troubleshooting\n\n### Version bump is wrong or misses commits\n\nCaused by a shallow git clone. Both modes need full history.\n\n```yaml\n- uses: actions/checkout@v4\n  with:\n    fetch-depth: 0\n```\n\n### Release step does nothing for a branch\n\nEach release step needs explicit `repository`, `rosdistro`, `track`, and\n`release-repository` inputs. The action will fail fast if any are missing.\n\n### \"Failed to push to rosdistro fork\" / \"fork not found\"\n\nbloom-release pushes to `https://github.com/\u003cBLOOM_GITHUB_USER\u003e/rosdistro`\nbefore opening a PR to `ros/rosdistro`. Ensure:\n\n1. `BLOOM_GITHUB_USER` is the owner of the PAT in `BLOOM_OAUTH_TOKEN`\n2. The PAT has `public_repo` and `workflow` scopes\n3. That user is allowed to create a fork of https://github.com/ros/rosdistro\n\n### `release-pr` job fails with a permission error\n\nCheck that the job has `permissions: contents: write` and\n`pull-requests: write`, and that \"Allow GitHub Actions to create and\napprove pull requests\" is enabled in repository settings.\n\n## Development\n\n### Setup\n\nThis project uses [mise](https://mise.jdx.dev) to manage tools and [pixi](https://pixi.sh) to manage the Python environment. Both are declared in `mise.toml` and `pyproject.toml` respectively.\n\n```bash\n# Clone the repository\ngit clone https://github.com/esteve/release-ros-robot.git\ncd release-ros-robot\n\n# Install mise (if not already installed)\ncurl https://mise.run | sh\n\n# Install pixi and all project dependencies\nmise install\npixi install\n\n# Install pre-commit hooks (recommended)\npixi run pre-commit install\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npixi run test\n\n# Run with coverage\npixi run pytest --cov=scripts --cov-report=term-missing\n\n# Run specific test\npixi run pytest tests/test_prepare_release.py::TestBumpVersion::test_bump_patch\n```\n\n### Code Quality\n\n```bash\n# Check formatting with Black\npixi run format-check\n\n# Lint with Ruff\npixi run lint\n\n# Type check with mypy\npixi run typecheck\n\n# Run all pre-commit hooks\npixi run pre-commit run --all-files\n```\n\nThe hooks automatically check for:\n- Python formatting (Black)\n- Linting (Ruff with auto-fixes)\n- Type checking (mypy)\n- YAML/JSON validation\n- Python syntax errors\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festeve%2Frelease-ros-robot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Festeve%2Frelease-ros-robot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festeve%2Frelease-ros-robot/lists"}