| 1 | --- |
| 2 | title: Automate versions and releases with release-please |
| 3 | description: Run release-please on Diffinery with the release-please action or its CLI: the workflow, the permissions and setting it needs, CI on release pull requests, and troubleshooting. |
| 4 | updated: 2026-10-26 |
| 5 | --- |
| 6 | |
| 7 | [release-please](https://github.com/googleapis/release-please) reads your Conventional Commits, keeps a release pull request open with the next version and changelog, and creates the tag and release when you merge it. It works on Diffinery as it does on GitHub: the `googleapis/release-please-action@v4` action runs unchanged, and the `release-please` CLI works with Diffinery's API URLs. Diffinery answers the GraphQL queries release-please sends (commit history with each commit's pull request, merged pull requests and releases) and the REST calls it makes (files, git data, pull requests, labels, tags and releases). |
| 8 | |
| 9 | ## Steps |
| 10 | |
| 11 | 1. **Keep your release-please files.** `release-please-config.json` and `.release-please-manifest.json` (or the action's `release-type` input) work as they are. An imported repository already has them. |
| 12 | 2. **Let workflows open pull requests.** Open the repository's **Settings → Actions** tab, check **Allow GitHub Actions to create and approve pull requests** under **Workflow permissions**, and click **Save**. This needs the admin role. It's off by default, as on GitHub, and without it the action fails with `GitHub Actions is not permitted to create pull requests.` See [GITHUB_TOKEN permissions](/docs/actions/workflow-permissions#creating-and-approving-pull-requests). |
| 13 | 3. **Add the workflow.** The same file as on GitHub: |
| 14 | |
| 15 | ```yaml |
| 16 | # .github/workflows/release-please.yml |
| 17 | on: |
| 18 | push: |
| 19 | branches: [main] |
| 20 | |
| 21 | permissions: |
| 22 | contents: write # tags and releases |
| 23 | pull-requests: write # the release pull request |
| 24 | issues: write # its labels |
| 25 | |
| 26 | jobs: |
| 27 | release-please: |
| 28 | runs-on: ubuntu-latest |
| 29 | outputs: |
| 30 | release_created: ${{ steps.release.outputs.release_created }} |
| 31 | tag_name: ${{ steps.release.outputs.tag_name }} |
| 32 | steps: |
| 33 | - uses: googleapis/release-please-action@v4 |
| 34 | id: release |
| 35 | with: |
| 36 | release-type: node # or leave it out and keep release-please-config.json |
| 37 | ``` |
| 38 | |
| 39 | The action's `github-api-url`, `github-graphql-url` and `changelog-host` inputs default to `${{ github.api_url }}`, `${{ github.graphql_url }}` and `${{ github.server_url }}`, which point at Diffinery, so you don't set them. Changelog links point at your repository on Diffinery. |
| 40 | 4. **Build and ship from the release.** Later jobs read the outputs, as on GitHub, for example to build and upload a mobile app only when a release was created: |
| 41 | |
| 42 | ```yaml |
| 43 | ship: |
| 44 | needs: release-please |
| 45 | if: ${{ needs.release-please.outputs.release_created == 'true' }} |
| 46 | runs-on: ubuntu-latest |
| 47 | steps: |
| 48 | - uses: actions/checkout@v4 |
| 49 | - run: ./scripts/ship.sh "${{ needs.release-please.outputs.tag_name }}" |
| 50 | ``` |
| 51 | |
| 52 | 5. **Merge the release pull request** when you want to release. Squash, merge commit and rebase merges all work. The next run of the workflow tags the merge, creates the release and relabels the pull request `autorelease: tagged`. |
| 53 | |
| 54 | ## CI on the release pull request |
| 55 | |
| 56 | As on GitHub, what a job's `GITHUB_TOKEN` does starts no new workflow runs, so a release pull request opened with it gets no `pull_request` runs. If your branch protection requires checks, give the action a token of its own: a [personal or agent token](/docs/accounts/tokens) with the `write` scope, stored as a secret. |
| 57 | |
| 58 | ```yaml |
| 59 | - uses: googleapis/release-please-action@v4 |
| 60 | with: |
| 61 | token: ${{ secrets.RELEASE_PLEASE_TOKEN }} |
| 62 | ``` |
| 63 | |
| 64 | Pull requests and pushes made with that token start workflows like anyone else's. If it's an [agent's](/docs/guides/ai-agent-with-guardrails) token, the agent rules apply: it opens and updates the release pull request, and a person merges it. |
| 65 | |
| 66 | ## The CLI |
| 67 | |
| 68 | Run release-please from a terminal or another CI system with Diffinery's REST and GraphQL URLs. `--graphql-url` is the address without `/graphql` (release-please adds it): |
| 69 | |
| 70 | ```sh |
| 71 | export DIFFINERY_TOKEN=dfy_... # a token with the write scope |
| 72 | npx release-please release-pr --repo-url acme/app --token "$DIFFINERY_TOKEN" \ |
| 73 | --api-url https://diffinery.com/api/v3 --graphql-url https://diffinery.com/api |
| 74 | npx release-please github-release --repo-url acme/app --token "$DIFFINERY_TOKEN" \ |
| 75 | --api-url https://diffinery.com/api/v3 --graphql-url https://diffinery.com/api |
| 76 | ``` |
| 77 | |
| 78 | `--target-branch` picks another branch than the default one. For changelog links that point at Diffinery when you use the CLI, add `"changelog-host": "https://diffinery.com"` to `release-please-config.json`; the action sets it for you. |
| 79 | |
| 80 | ## Troubleshooting |
| 81 | |
| 82 | | Message | Fix | |
| 83 | | --- | --- | |
| 84 | | `GitHub Actions is not permitted to create pull requests.` | Check **Allow GitHub Actions to create and approve pull requests** (step 2), or use a token of its own. | |
| 85 | | `Resource not accessible by integration (the workflow's GITHUB_TOKEN needs permissions: ...)` | Add the `permissions:` from step 3 to the workflow or job. | |
| 86 | | `release-please failed: Error updating ref heads/release-please--branches--...` (the API answered ``refusing to allow a GitHub App to create or update workflow `...` without `workflows` permission``) | A workflow file changed on the base branch while the release pull request was open. Rebuilding the release branch on the new base would change workflow files on it, which a job's `GITHUB_TOKEN` may never do on Diffinery. Merge or close the release pull request and delete its branch (the next run opens a fresh one), or give the action a [token of its own](#ci-on-the-release-pull-request). | |
| 87 | | `Could not find commits for branch <name> - it likely does not exist.` | The branch in `target-branch` (or the default branch) doesn't exist, or the token can't read the repository. | |
| 88 | | Changelog links go to github.com | Set `changelog-host` (CLI), or check that the action's `changelog-host` input isn't set to GitHub. | |
| 89 | | `No commits for path: ., skipping` | Nothing since the last release follows Conventional Commits (`feat:`, `fix:`, `feat!:` and so on), so there's nothing to release. | |
| 90 | |
| 91 | ## Related |
| 92 | |
| 93 | - [Releases](/docs/collaboration/releases): tags, drafts, notes and assets. |
| 94 | - [GraphQL API](/docs/reference/graphql-api): the queries Diffinery answers. |
| 95 | - [Move your GitHub Actions workflows to Diffinery](/docs/guides/move-github-actions-workflows). |