Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions EXAMPLE_WORKFLOW.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Example workflow demonstrating the new feature from Issue #4111
# This workflow shows how PR title and body are automatically defaulted from commit message

name: Example - Auto PR Title/Body

on:
workflow_dispatch:

jobs:
create-pr-with-auto-defaults:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# Make some changes
- name: Update files
run: |
echo "Updated content" > example.txt
date > timestamp.txt

# Create PR with automatic title/body from commit
# The PR will have:
# Title: "Update AGP sources to the latest"
# Body: "_Auto-generated by `dump-sources` Github workflow._"
- name: Create Pull Request (Auto Title/Body)
uses: peter-evans/create-pull-request@v7
with:
commit-message: |
Update AGP sources to the latest

_Auto-generated by `dump-sources` Github workflow._
branch: actions/dump-sources
delete-branch: true
# Note: title and body are NOT specified, so they will be
# automatically set from the commit message above

create-pr-with-custom-values:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# Make some changes
- name: Update files
run: |
echo "Updated content" > example.txt

# Create PR with custom title/body (overrides auto-default)
# The PR will have the custom values below, NOT the commit message
- name: Create Pull Request (Custom Title/Body)
uses: peter-evans/create-pull-request@v7
with:
commit-message: |
Update AGP sources to the latest

_Auto-generated by `dump-sources` Github workflow._
title: Custom PR Title
body: Custom PR Description
branch: actions/custom-pr
delete-branch: true

create-pr-multiple-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# Make multiple commits
- name: Create multiple commits
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

echo "First change" > file1.txt
git add file1.txt
git commit -m "First commit"

echo "Second change" > file2.txt
git add file2.txt
git commit -m "Second commit"

# Create PR - will use default title/body since there are multiple commits
# The PR will have:
# Title: "Changes by create-pull-request action"
# Body: "Automated changes by [create-pull-request](...) GitHub action"
- name: Create Pull Request (Multiple Commits)
uses: peter-evans/create-pull-request@v7
with:
branch: actions/multiple-commits
delete-branch: true
# Note: Multiple commits means auto-default doesn't apply
218 changes: 218 additions & 0 deletions __test__/create-pull-request.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import {Commit} from '../lib/git-command-manager'

describe('create-pull-request PR title and body defaulting', () => {
const defaultTitle = 'Changes by create-pull-request action'
const defaultBody =
'Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action'

test('should use commit subject as title for single commit when title is default', () => {
const commit: Commit = {
sha: 'abc123',
tree: 'tree123',
parents: ['parent123'],
signed: false,
subject: 'Update AGP sources to the latest',
body: '_Auto-generated by `dump-sources` Github workflow._',
changes: [],
unparsedChanges: []
}

const branchCommits = [commit]
let title = defaultTitle
let body = defaultBody

// Simulate the logic from create-pull-request.ts
if (branchCommits.length === 1) {
const singleCommit = branchCommits[0]
if (title === defaultTitle) {
title = singleCommit.subject
}
if (body === defaultBody) {
if (singleCommit.body && singleCommit.body.trim().length > 0) {
body = singleCommit.body
}
}
}

expect(title).toEqual('Update AGP sources to the latest')
expect(body).toEqual('_Auto-generated by `dump-sources` Github workflow._')
})

test('should not override custom title and body', () => {
const commit: Commit = {
sha: 'abc123',
tree: 'tree123',
parents: ['parent123'],
signed: false,
subject: 'Update AGP sources to the latest',
body: '_Auto-generated by `dump-sources` Github workflow._',
changes: [],
unparsedChanges: []
}

const branchCommits = [commit]
let title = 'Custom Title'
let body = 'Custom Body'

// Simulate the logic from create-pull-request.ts
if (branchCommits.length === 1) {
const singleCommit = branchCommits[0]
if (title === defaultTitle) {
title = singleCommit.subject
}
if (body === defaultBody) {
if (singleCommit.body && singleCommit.body.trim().length > 0) {
body = singleCommit.body
}
}
}

expect(title).toEqual('Custom Title')
expect(body).toEqual('Custom Body')
})

test('should not default for multiple commits', () => {
const commit1: Commit = {
sha: 'abc123',
tree: 'tree123',
parents: ['parent123'],
signed: false,
subject: 'First commit',
body: 'First commit body',
changes: [],
unparsedChanges: []
}

const commit2: Commit = {
sha: 'def456',
tree: 'tree456',
parents: ['abc123'],
signed: false,
subject: 'Second commit',
body: 'Second commit body',
changes: [],
unparsedChanges: []
}

const branchCommits = [commit1, commit2]
let title = defaultTitle
let body = defaultBody

// Simulate the logic from create-pull-request.ts
if (branchCommits.length === 1) {
const singleCommit = branchCommits[0]
if (title === defaultTitle) {
title = singleCommit.subject
}
if (body === defaultBody) {
if (singleCommit.body && singleCommit.body.trim().length > 0) {
body = singleCommit.body
}
}
}

expect(title).toEqual(defaultTitle)
expect(body).toEqual(defaultBody)
})

test('should handle commit with empty body', () => {
const commit: Commit = {
sha: 'abc123',
tree: 'tree123',
parents: ['parent123'],
signed: false,
subject: 'Update files',
body: '',
changes: [],
unparsedChanges: []
}

const branchCommits = [commit]
let title = defaultTitle
let body = defaultBody

// Simulate the logic from create-pull-request.ts
if (branchCommits.length === 1) {
const singleCommit = branchCommits[0]
if (title === defaultTitle) {
title = singleCommit.subject
}
if (body === defaultBody) {
if (singleCommit.body && singleCommit.body.trim().length > 0) {
body = singleCommit.body
}
}
}

expect(title).toEqual('Update files')
expect(body).toEqual(defaultBody) // Should keep default when commit body is empty
})

test('should handle commit with multi-line body', () => {
const commit: Commit = {
sha: 'abc123',
tree: 'tree123',
parents: ['parent123'],
signed: false,
subject: 'Update documentation',
body: 'This is a detailed commit message.\n\nIt has multiple paragraphs.\n\n- Item 1\n- Item 2',
changes: [],
unparsedChanges: []
}

const branchCommits = [commit]
let title = defaultTitle
let body = defaultBody

// Simulate the logic from create-pull-request.ts
if (branchCommits.length === 1) {
const singleCommit = branchCommits[0]
if (title === defaultTitle) {
title = singleCommit.subject
}
if (body === defaultBody) {
if (singleCommit.body && singleCommit.body.trim().length > 0) {
body = singleCommit.body
}
}
}

expect(title).toEqual('Update documentation')
expect(body).toEqual(
'This is a detailed commit message.\n\nIt has multiple paragraphs.\n\n- Item 1\n- Item 2'
)
})

test('should handle commit with whitespace-only body', () => {
const commit: Commit = {
sha: 'abc123',
tree: 'tree123',
parents: ['parent123'],
signed: false,
subject: 'Update files',
body: ' \n\n ',
changes: [],
unparsedChanges: []
}

const branchCommits = [commit]
let title = defaultTitle
let body = defaultBody

// Simulate the logic from create-pull-request.ts
if (branchCommits.length === 1) {
const singleCommit = branchCommits[0]
if (title === defaultTitle) {
title = singleCommit.subject
}
if (body === defaultBody) {
if (singleCommit.body && singleCommit.body.trim().length > 0) {
body = singleCommit.body
}
}
}

expect(title).toEqual('Update files')
expect(body).toEqual(defaultBody) // Should keep default when commit body is only whitespace
})
})
20 changes: 20 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,26 @@ function createPullRequest(inputs) {
core.endGroup();
}
if (result.hasDiffWithBase) {
// Default PR title and body from commit message for single-commit PRs
// This mimics GitHub's web interface behavior
const defaultTitle = 'Changes by create-pull-request action';
const defaultBody = 'Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action';
if (result.branchCommits.length === 1) {
const commit = result.branchCommits[0];
// Use commit subject as title if title is at default value
if (inputs.title === defaultTitle) {
inputs.title = commit.subject;
core.info(`Defaulting pull request title to commit subject: '${inputs.title}'`);
}
// Use commit body as PR body if body is at default value
if (inputs.body === defaultBody) {
// Use commit body if it exists, otherwise keep the default
if (commit.body && commit.body.trim().length > 0) {
inputs.body = commit.body;
core.info(`Defaulting pull request body to commit body (${commit.body.length} characters)`);
}
}
}
core.startGroup('Create or update the pull request');
const pull = yield ghPull.createOrUpdatePullRequest(inputs, baseRemote.repository, branchRepository);
outputs.set('pull-request-number', pull.number.toString());
Expand Down
Loading