@@ -246,33 +246,66 @@ jobs:
246246 ISSUE_NUMBER : ${{ inputs.issue-number }}
247247 ISSUE_TITLE : ${{ steps.issue.outputs.title }}
248248 run : |
249- if [ -f /tmp/pr-title.txt ]; then
250- PR_TITLE=$(head -n 1 /tmp/pr-title.txt)
251- echo "pr_title=$PR_TITLE" >> "$GITHUB_OUTPUT"
252- else
253- echo "pr_title=Fix phpstan/phpstan#$ISSUE_NUMBER: $ISSUE_TITLE" >> "$GITHUB_OUTPUT"
254- fi
249+ set -euo pipefail
250+
251+ # Writes a (possibly multiline) value from a file into $GITHUB_OUTPUT
252+ # using the heredoc-style delimited syntax. This is robust against:
253+ # - files without a trailing newline (the runner requires the
254+ # closing delimiter to be on its own line, otherwise it errors
255+ # with "Matching delimiter not found")
256+ # - CRLF line endings
257+ # - the (vanishingly unlikely) chance that the random delimiter
258+ # happens to appear inside the file content
259+ write_multiline_output() {
260+ local key=$1
261+ local file=$2
262+ local delimiter
263+ local content
264+
265+ # Strip CRs and ensure exactly one trailing newline so the closing
266+ # delimiter always lands on its own line.
267+ content=$(tr -d '\r' < "$file")
268+
269+ # Pick a delimiter that is guaranteed not to appear in the content.
270+ while :; do
271+ delimiter="GHA_EOF_$(openssl rand -hex 16)"
272+ if ! printf '%s' "$content" | grep -qxF "$delimiter"; then
273+ break
274+ fi
275+ done
255276
256- if [ -f /tmp/commit-message.txt ]; then
257- delimiter="EOF_$(openssl rand -hex 16)"
258277 {
259- echo "commit_message<<${ delimiter} "
260- cat /tmp/commit-message.txt
261- echo "${ delimiter} "
278+ printf '%s<<% s\n' "$key" "$ delimiter"
279+ printf '%s\n' "$content"
280+ printf '%s\n' "$ delimiter"
262281 } >> "$GITHUB_OUTPUT"
282+ }
283+
284+ write_singleline_output() {
285+ local key=$1
286+ local value=$2
287+ # Single-line outputs cannot contain newlines; collapse defensively.
288+ value=$(printf '%s' "$value" | tr '\r\n' ' ')
289+ printf '%s=%s\n' "$key" "$value" >> "$GITHUB_OUTPUT"
290+ }
291+
292+ if [ -s /tmp/pr-title.txt ]; then
293+ PR_TITLE=$(head -n 1 /tmp/pr-title.txt | tr -d '\r')
294+ write_singleline_output "pr_title" "$PR_TITLE"
263295 else
264- echo "commit_message= Fix #$ISSUE_NUMBER" >> "$GITHUB_OUTPUT "
296+ write_singleline_output "pr_title" " Fix phpstan/phpstan #$ISSUE_NUMBER: $ISSUE_TITLE "
265297 fi
266298
267- if [ -f /tmp/pr-description.md ]; then
268- delimiter="EOF_$(openssl rand -hex 16)"
269- {
270- echo "pr_body<<${delimiter}"
271- cat /tmp/pr-description.md
272- echo "${delimiter}"
273- } >> "$GITHUB_OUTPUT"
299+ if [ -s /tmp/commit-message.txt ]; then
300+ write_multiline_output "commit_message" /tmp/commit-message.txt
301+ else
302+ write_singleline_output "commit_message" "Fix #$ISSUE_NUMBER"
303+ fi
304+
305+ if [ -s /tmp/pr-description.md ]; then
306+ write_multiline_output "pr_body" /tmp/pr-description.md
274307 else
275- echo "pr_body= Fixes phpstan/phpstan#$ISSUE_NUMBER" >> "$GITHUB_OUTPUT "
308+ write_singleline_output "pr_body" " Fixes phpstan/phpstan#$ISSUE_NUMBER"
276309 fi
277310
278311 - name: "Create Pull Request"
0 commit comments