Skip to content
Merged
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
134 changes: 134 additions & 0 deletions .github/actions/create-pull-request/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: 'Create Pull Request'
description: 'Creates or updates a pull request for changes to the repository'
inputs:
token:
description: 'GitHub token for authentication'
required: true
branch:
description: 'The pull request branch name'
required: true
base:
description: 'The base branch for the pull request'
required: false
default: 'main'
title:
description: 'The title of the pull request'
required: true
body:
description: 'The body of the pull request'
required: true
labels:
description: 'A newline-separated list of labels'
required: false
default: ''
commit-message:
description: 'The commit message to use when committing changes'
required: false
default: '[create-pull-request] automated change'
branch-already-exists:
description: 'Set to true if the branch is already pushed remotely (skips commit/push)'
required: false
default: 'false'
outputs:
pull-request-number:
description: 'The pull request number'
value: ${{ steps.create-pr.outputs.pull-request-number }}
pull-request-url:
description: 'The URL of the pull request'
value: ${{ steps.create-pr.outputs.pull-request-url }}
pull-request-operation:
description: 'The pull request operation performed (created, updated, none)'
value: ${{ steps.create-pr.outputs.pull-request-operation }}
runs:
using: 'composite'
steps:
- name: Configure git authentication
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
run: |
# Use the provided token for both git and gh operations
gh auth setup-git

- name: Commit and push changes
if: inputs.branch-already-exists != 'true'
id: commit-and-push
shell: bash
env:
BRANCH: ${{ inputs.branch }}
COMMIT_MESSAGE: ${{ inputs.commit-message }}
run: |
# Check for any changes (staged, unstaged, or untracked)
if git diff --quiet && git diff --cached --quiet && [ -z "$(git ls-files --others --exclude-standard)" ]; then
echo "No changes to commit"
echo "has_changes=false" >> $GITHUB_OUTPUT
exit 0
fi

echo "has_changes=true" >> $GITHUB_OUTPUT

git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

# Create or reset branch
git checkout -B "$BRANCH"
git add -A
git commit -m "$COMMIT_MESSAGE"
git push -f origin "$BRANCH"

Comment thread
joperezr marked this conversation as resolved.
- name: Create or update pull request
id: create-pr
if: inputs.branch-already-exists == 'true' || steps.commit-and-push.outputs.has_changes == 'true'
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
BRANCH: ${{ inputs.branch }}
BASE: ${{ inputs.base }}
PR_TITLE: ${{ inputs.title }}
PR_BODY: ${{ inputs.body }}
LABELS: ${{ inputs.labels }}
run: |
# Check if a PR already exists for this branch
EXISTING_PR=$(gh pr list --head "$BRANCH" --base "$BASE" --json number,url --jq '.[0] // empty')

if [ -n "$EXISTING_PR" ]; then
PR_NUMBER=$(echo "$EXISTING_PR" | jq -r '.number')
PR_URL=$(echo "$EXISTING_PR" | jq -r '.url')
Comment on lines +92 to +96
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step parses EXISTING_PR with jq, which adds an extra tool dependency. Since gh already supports --jq, you can avoid relying on jq being installed (especially on non-standard/self-hosted runners) by extracting number/url directly in the gh pr list call(s).

Suggested change
EXISTING_PR=$(gh pr list --head "$BRANCH" --base "$BASE" --json number,url --jq '.[0] // empty')
if [ -n "$EXISTING_PR" ]; then
PR_NUMBER=$(echo "$EXISTING_PR" | jq -r '.number')
PR_URL=$(echo "$EXISTING_PR" | jq -r '.url')
PR_NUMBER=$(gh pr list --head "$BRANCH" --base "$BASE" --json number --jq '.[0].number // empty')
if [ -n "$PR_NUMBER" ]; then
PR_URL=$(gh pr list --head "$BRANCH" --base "$BASE" --json url --jq '.[0].url // empty')

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't fix. jq is pre-installed on all GitHub-hosted runners (ubuntu-latest, windows-latest, macos-latest) and is already used extensively in other steps of release-github-tasks.yml. The extra gh pr list call suggested would double the API requests for the existing-PR path. Not worth the churn for a non-issue.

echo "Pull request #$PR_NUMBER already exists: $PR_URL"
echo "pull-request-number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "pull-request-url=$PR_URL" >> $GITHUB_OUTPUT
echo "pull-request-operation=none" >> $GITHUB_OUTPUT
else
Comment thread
joperezr marked this conversation as resolved.
# Build label arguments as a bash array (avoids eval/injection)
LABEL_ARGS=()
if [ -n "$LABELS" ]; then
while IFS= read -r label; do
label=$(echo "$label" | xargs) # trim whitespace
if [ -n "$label" ]; then
LABEL_ARGS+=(--label "$label")
fi
done <<< "$LABELS"
fi

# Write body to a temp file to avoid shell quoting issues with special characters
BODY_FILE=$(mktemp)
trap 'rm -f "$BODY_FILE"' EXIT
printf '%s\n' "$PR_BODY" > "$BODY_FILE"

# Create the pull request without eval — all args are properly quoted
PR_URL=$(gh pr create \
--title "$PR_TITLE" \
--body-file "$BODY_FILE" \
--base "$BASE" \
--head "$BRANCH" \
"${LABEL_ARGS[@]}")

rm -f "$BODY_FILE"
trap - EXIT

PR_NUMBER=$(gh pr view "$BRANCH" --json number --jq '.number')
echo "Created pull request #$PR_NUMBER: $PR_URL"
echo "pull-request-number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "pull-request-url=$PR_URL" >> $GITHUB_OUTPUT
echo "pull-request-operation=created" >> $GITHUB_OUTPUT
fi
2 changes: 1 addition & 1 deletion .github/workflows/generate-api-diffs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
private-key: ${{ secrets.ASPIRE_BOT_PRIVATE_KEY }}

- name: Create or update pull request
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
branch: update-api-diffs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/generate-ats-diffs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
private-key: ${{ secrets.ASPIRE_BOT_PRIVATE_KEY }}

- name: Create or update pull request
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
branch: update-ats-diffs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/refresh-manifests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
private-key: ${{ secrets.ASPIRE_BOT_PRIVATE_KEY }}

- name: Create or update pull request
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
branch: update-manifests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/refresh-typescript-sdks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
./eng/refreshTypeScriptSdks.ps1

- name: Create or update pull request
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1
uses: ./.github/actions/create-pull-request
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: update-typescript-playground-sdks
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/release-github-tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ jobs:

- name: Create Merge PR
if: steps.check-pr.outputs.pr_exists != 'true' && inputs.dry_run != true
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1 # v1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
title: "Merge ${{ inputs.release_branch }} to main after v${{ inputs.release_version }} release"
Expand All @@ -372,6 +372,7 @@ jobs:
*Created automatically by the release workflow.*
branch: ${{ inputs.release_branch }}
base: main
branch-already-exists: 'true'
labels: |
area-infrastructure
release-automation
Expand Down Expand Up @@ -476,7 +477,7 @@ jobs:

- name: Create Baseline PR
if: steps.check-pr.outputs.pr_exists != 'true' && inputs.dry_run != true
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1 # v1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
title: "Update PackageValidationBaselineVersion to ${{ inputs.release_version }}"
Expand All @@ -492,6 +493,7 @@ jobs:
*Created automatically by the release workflow.*
branch: update-baseline-${{ inputs.release_version }}
base: main
branch-already-exists: 'true'
labels: |
area-infrastructure
release-automation
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-ai-foundry-models.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
private-key: ${{ secrets.ASPIRE_BOT_PRIVATE_KEY }}

- name: Create or update pull request
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
branch: update-ai-foundry-models
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:

- name: Create Pull Request
id: create-pr
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
branch: update-dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-github-models.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
private-key: ${{ secrets.ASPIRE_BOT_PRIVATE_KEY }}

- name: Create or update pull request
uses: dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1
uses: ./.github/actions/create-pull-request
with:
token: ${{ steps.app-token.outputs.token }}
branch: update-github-models
Expand Down
2 changes: 1 addition & 1 deletion docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ The pipeline uses the `Aspire-Release-Secrets` variable group. Note that NuGet p
The workflow uses only pre-approved actions:

- `actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683` (v4)
- `dotnet/actions-create-pull-request@e8d799aa1f8b17f324f9513832811b0a62f1e0b1` (v1)
- `./.github/actions/create-pull-request` (local composite action)

## Troubleshooting

Expand Down
Loading