Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 7, 2025

Problem

When using both body_path and body inputs, if the file specified in body_path doesn't exist, the action crashes with an ENOENT exception instead of falling back to the body input as documented in the README.

The README states:

💡 When providing a body and body_path at the same time, body_path will be attempted first, then falling back on body if the path can not be read from.

However, the current implementation uses readFileSync without error handling, causing the action to abort when the file is missing.

Solution

Modified the releaseBody function in src/util.ts to safely attempt reading the body_path file with proper error handling:

  • Wrapped readFileSync in a try-catch block to handle file read errors (ENOENT, permission errors, etc.)
  • Logs a concise warning message when fallback occurs: ⚠️ Failed to read body_path "<path>" (<error_code>). Falling back to 'body' input.
  • Returns the body input as fallback when file read fails
  • Returns undefined if both body_path fails and body is not provided

Example Usage

- name: Release
  uses: softprops/action-gh-release@v2
  if: startsWith(github.ref, 'refs/tags/v')
  with:
    body_path: pipeline-changes.txt  # May not exist
    body: 'Default release notes'     # Fallback if file is missing
    files: |
      App*.exe

With this fix, if pipeline-changes.txt doesn't exist, the action will use 'Default release notes' instead of crashing.

Testing

Added comprehensive test coverage:

  • ✅ Falls back to body when body_path file is missing
  • ✅ Returns undefined when both body_path fails and body is not provided
  • ✅ Existing tests pass (body_path takes precedence when file exists)
  • ✅ All 39 tests passing with full backward compatibility

Fixes the issue where missing body_path files cause action failure even when a fallback body is configured.

Original prompt

This section details on the original issue you should resolve

<issue_title>Missing body_path file causes abort of action even if fallback body has been set</issue_title>
<issue_description>Using:

    - name: Release
      uses: softprops/action-gh-release@v2
      if: startsWith(github.ref, 'refs/tags/v')
      with:
        body_path: pipeline-changes.txt
        body: '----'
        files: |
          App*.exe

When body_path file read is attempted (readFileSync at

export const releaseBody = (config: Config): string | undefined => {
), if the file does not exist it causes an ENOENT exception and crashes the action.

Main README.md states:
💡 When providing a body and body_path at the same time, body_path will be attempted first, then falling back on body if the path can not be read from.

Any exception should be captured and the fallback body used.</issue_description>

<agent_instructions>We have a bug: when with.body_path points to a non-existent file, the Action crashes with ENOENT instead of falling back to with.body. The README promises: “When providing a body and body_path at the same time, body_path will be attempted first, then falling back on body if the path can not be read from.”

Please implement the fallback and add tests.

What to change

src/util.ts

Modify releaseBody so it safely attempts to read input_body_path.

If the read throws or returns nothing, return config.input_body.

Do not throw on ENOENT or any read error; log a concise warning instead.

Suggested shape:

import { readFileSync } from 'fs';

export const releaseBody = (config: Config): string | undefined => {
if (config.input_body_path) {
try {
const contents = readFileSync(config.input_body_path, 'utf8');
return contents;
} catch (err: any) {
console.warn(
⚠️ Failed to read body_path "${config.input_body_path}" (${err?.code ?? 'ERR'}). Falling back to 'body' input.,
);
}
}
return config.input_body;
};

Tests in tests/util.test.ts
Add coverage for the fallback behavior:

“falls back to body when body_path is missing”

assert.equal(
releaseBody({
github_ref: '',
github_repository: '',
github_token: '',
input_body: 'fallback-body',
input_body_path: 'tests/does-not-exist.txt',
input_draft: false,
input_prerelease: false,
input_files: [],
input_overwrite_files: undefined,
input_preserve_order: undefined,
input_name: undefined,
input_tag_name: undefined,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false,
input_make_latest: undefined,
}),
'fallback-body',
);

“returns undefined when body_path is missing and body is not provided”

assert.equal(
releaseBody({
github_ref: '',
github_repository: '',
github_token: '',
input_body: undefined,
input_body_path: 'tests/does-not-exist.txt',
input_draft: false,
input_prerelease: false,
input_files: [],
input_overwrite_files: undefined,
input_preserve_order: undefined,
input_name: undefined,
input_tag_name: undefined,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false,
input_make_latest: undefined,
}),
undefined,
);

(Existing tests for body_path taking precedence over body should remain green.)

Run & commit

Run: npm ci && npm test

If green, create two commits:

fix: gracefully fallback to body when body_path cannot be read

test: add fallback tests for body_path ENOENT

Finally, show me:

The diff for src/util.ts and tests/util.test.ts.

The vitest summary output.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Fixes #664

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Missing body_path file causes abort of action even if fallback body has been set fix: gracefully fallback to body when body_path cannot be read Oct 7, 2025
Copilot AI requested a review from chenrui333 October 7, 2025 03:17
Copilot finished work on behalf of chenrui333 October 7, 2025 03:17
@chenrui333 chenrui333 marked this pull request as ready for review October 7, 2025 03:50
@chenrui333 chenrui333 merged commit f38efde into master Oct 7, 2025
2 checks passed
@chenrui333 chenrui333 deleted the copilot/fix-b77e322d-b384-4bfb-8bed-e6a6c53e14ca branch October 7, 2025 03:50
@chenrui333 chenrui333 added the bug Something isn't working label Oct 11, 2025
mergify bot added a commit to robfrank/linklift that referenced this pull request Oct 15, 2025
Bumps the github-actions group with 2 updates: [softprops/action-gh-release](https://github.com/softprops/action-gh-release) and [ruby/setup-ruby](https://github.com/ruby/setup-ruby).
Updates `softprops/action-gh-release` from 2.3.4 to 2.4.1
Release notes

*Sourced from [softprops/action-gh-release's releases](https://github.com/softprops/action-gh-release/releases).*

> v2.4.1
> ------
>
> What's Changed
> --------------
>
> ### Other Changes 🔄
>
> * fix(util): support brace expansion globs containing commas in parseInputFiles by [`@​Copilot`](https://github.com/Copilot) in [softprops/action-gh-release#672](https://redirect.github.com/softprops/action-gh-release/pull/672)
> * fix: gracefully fallback to body when body\_path cannot be read by [`@​Copilot`](https://github.com/Copilot) in [softprops/action-gh-release#671](https://redirect.github.com/softprops/action-gh-release/pull/671)
>
> **Full Changelog**: <softprops/action-gh-release@v2...v2.4.1>
>
> v2.4.0
> ------
>
> What's Changed
> --------------
>
> ### Exciting New Features 🎉
>
> * feat(action): respect working\_directory for files globs by [`@​stephenway`](https://github.com/stephenway) in [softprops/action-gh-release#667](https://redirect.github.com/softprops/action-gh-release/pull/667)
>
> ### Other Changes 🔄
>
> * chore(deps): bump the npm group with 2 updates by [`@​dependabot`](https://github.com/dependabot)[bot] in [softprops/action-gh-release#668](https://redirect.github.com/softprops/action-gh-release/pull/668)
>
> **Full Changelog**: <softprops/action-gh-release@v2.3.4...v2.4.0>


Changelog

*Sourced from [softprops/action-gh-release's changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md).*

> 2.4.1
> -----
>
> What's Changed
> --------------
>
> ### Other Changes 🔄
>
> * fix(util): support brace expansion globs containing commas in parseInputFiles by [`@​Copilot`](https://github.com/Copilot) in [softprops/action-gh-release#672](https://redirect.github.com/softprops/action-gh-release/pull/672)
> * fix: gracefully fallback to body when body\_path cannot be read by [`@​Copilot`](https://github.com/Copilot) in [softprops/action-gh-release#671](https://redirect.github.com/softprops/action-gh-release/pull/671)
>
> 2.4.0
> -----
>
> What's Changed
> --------------
>
> ### Exciting New Features 🎉
>
> * feat(action): respect working\_directory for files globs by [`@​stephenway`](https://github.com/stephenway) in [softprops/action-gh-release#667](https://redirect.github.com/softprops/action-gh-release/pull/667)
>
> 2.3.4
> -----
>
> What's Changed
> --------------
>
> ### Bug fixes 🐛
>
> * fix(action): handle 422 already\_exists race condition by [`@​stephenway`](https://github.com/stephenway) in [softprops/action-gh-release#665](https://redirect.github.com/softprops/action-gh-release/pull/665)
>
> ### Other Changes 🔄
>
> * dependency updates
>
> 2.3.3
> -----
>
> What's Changed
> --------------
>
> ### Exciting New Features 🎉
>
> * feat: add input option `overwrite_files` by [`@​asfernandes`](https://github.com/asfernandes) in [softprops/action-gh-release#343](https://redirect.github.com/softprops/action-gh-release/pull/343)
>
> ### Other Changes 🔄
>
> * dependency updates
>
> 2.3.2
> -----
>
> * fix: revert fs `readableWebStream` change
>
> 2.3.1
> -----
>
> ### Bug fixes 🐛
>
> * fix: fix file closing issue by [`@​WailGree`](https://github.com/WailGree) in [softprops/action-gh-release#629](https://redirect.github.com/softprops/action-gh-release/pull/629)

... (truncated)


Commits

* [`6da8fa9`](softprops/action-gh-release@6da8fa9) release 2.4.1
* [`f38efde`](softprops/action-gh-release@f38efde) fix: gracefully fallback to body when body\_path cannot be read ([#671](https://redirect.github.com/softprops/action-gh-release/issues/671))
* [`cec1a11`](softprops/action-gh-release@cec1a11) fix(util): support brace expansion globs containing commas in parseInputFiles...
* [`aec2ec5`](softprops/action-gh-release@aec2ec5) release 2.4.0
* [`4db716b`](softprops/action-gh-release@4db716b) feat: respect working\_directory for files globs; add input and tests ([#667](https://redirect.github.com/softprops/action-gh-release/issues/667))
* [`14820f2`](softprops/action-gh-release@14820f2) chore(deps): bump the npm group with 2 updates ([#668](https://redirect.github.com/softprops/action-gh-release/issues/668))
* See full diff in [compare view](softprops/action-gh-release@62c96d0...6da8fa9)
  
Updates `ruby/setup-ruby` from 1.263.0 to 1.265.0
Release notes

*Sourced from [ruby/setup-ruby's releases](https://github.com/ruby/setup-ruby/releases).*

> v1.265.0
> --------
>
> What's Changed
> --------------
>
> * Update CRuby releases on Windows by [`@​ruby-builder-bot`](https://github.com/ruby-builder-bot) in [ruby/setup-ruby#817](https://redirect.github.com/ruby/setup-ruby/pull/817)
>
> **Full Changelog**: <ruby/setup-ruby@v1.264.0...v1.265.0>
>
> v1.264.0
> --------
>
> What's Changed
> --------------
>
> * Add ruby-3.4.7 by [`@​ruby-builder-bot`](https://github.com/ruby-builder-bot) in [ruby/setup-ruby#815](https://redirect.github.com/ruby/setup-ruby/pull/815)
>
> **Full Changelog**: <ruby/setup-ruby@v1.263.0...v1.264.0>


Commits

* [`ab177d4`](ruby/setup-ruby@ab177d4) Update CRuby releases on Windows
* [`6797dcb`](ruby/setup-ruby@6797dcb) Add ruby-3.4.7
* [`a16e0e6`](ruby/setup-ruby@a16e0e6) Test on macos-15-intel too
* See full diff in [compare view](ruby/setup-ruby@0481980...ab177d4)
  
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore  major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
- `@dependabot ignore  minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency
- `@dependabot unignore  ` will remove the ignore condition of the specified dependency and ignore conditions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing body_path file causes abort of action even if fallback body has been set

2 participants