* GitCommandManager: add a function to get a file's contents at a specific revision
* use showFileAtRef instead of readFileBase64
* Teach GitCommandManager.exec about an object of exec parameters so we can add more
* Encode the showFiletRef output as base64 out of the gate
* Fix missing async for function
* Use Buffer.concat to avoid issues with partial data streams
* formatting
---------
Co-authored-by: gustavderdrache <alex.ford@determinate.systems>
The option suggested here (Read only) is not an option, and wouldn't mean/do anything - you can read these files if you have access to the repo files. The description says this is needed if the PR could change the workflow files, so you need "Read and Write". Pretty sure this is just a typo, copied from the line below instead of the line above.
2024-09-16 09:49:30 -07:00
24 changed files with 3032 additions and 28504 deletions
- commits made during the workflow that have not been pushed
2. Commit all changes to a new branch, or update an existing pull request branch.
3. Create a pull request to merge the new branch into the base—the branch checked out in the workflow.
3. Create or update a pull request to merge the branch into the base—the branch checked out in the workflow.
## Documentation
@ -53,7 +53,7 @@ All inputs are **optional**. If not set, sensible defaults will be used.
| `token` | The token that the action will use to create and update the pull request. See [token](#token). | `GITHUB_TOKEN` |
| `branch-token` | The token that the action will use to create and update the branch. See [branch-token](#branch-token). | Defaults to the value of `token` |
| `path` | Relative path under `GITHUB_WORKSPACE` to the repository. | `GITHUB_WORKSPACE` |
| `add-paths` | A comma or newline-separated list of file paths to commit. Paths should follow git's [pathspec](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec) syntax. If no paths are specified, all new and modified files are added. See [Add specific paths](#add-specific-paths). | |
| `add-paths` | A comma or newline-separated list of file paths to commit. Paths should follow git's [pathspec](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec) syntax. See [Add specific paths](#add-specific-paths). | If no paths are specified, all new and modified files are added. |
| `commit-message` | The message to use when committing changes. See [commit-message](#commit-message). | `[create-pull-request] automated change` |
| `committer` | The committer name and email address in the format `Display Name <email@address.com>`. Defaults to the GitHub Actions bot user on github.com. | `github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>` |
| `author` | The author name and email address in the format `Display Name <email@address.com>`. Defaults to the user who triggered the workflow run. | `${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>` |
@ -99,7 +99,7 @@ Other token options:
#### branch-token
The action first creates a branch, and then creates a pull request for the branch.
For some rare use cases it can be useful, or even neccessary, to use different tokens for these operations.
For some rare use cases it can be useful, or even necessary, to use different tokens for these operations.
It is not advisable to use this input unless you know you need to.
--`+a;constt=newUint8Array(a.length);for(letn=0;n<a.length;n++)t[n]=a.charCodeAt(n),this.boundaryChars[t[n]]=!0;this.boundary=t,this.lookbehind=newUint8Array(this.boundary.length+8),this.state=S.START_BOUNDARY}write(a){lett=0;constn=a.length;letE=this.index,{lookbehind:d,boundary:h,boundaryChars:H,index:e,state:o,flags:l}=this;constb=this.boundary.length,m=b-1,O=a.length;letr,P;constu=c(D=>{this[D+"Mark"]=t},"mark"),i=c(D=>{deletethis[D+"Mark"]},"clear"),T=c((D,p,R,g)=>{(p===void0||p!==R)&&this[D](g&&g.subarray(p,R))},"callback"),L=c((D,p)=>{constR=D+"Mark";Rinthis&&(p?(T(D,this[R],t,a),deletethis[R]):(T(D,this[R],a.length,a),this[R]=0))},"dataCallback");for(t=0;t<n;t++)switch(r=a[t],o){caseS.START_BOUNDARY:if(e===h.length-2){if(r===HYPHEN)l|=F.LAST_BOUNDARY;elseif(r!==CR)return;e++;break}elseif(e-1===h.length-2){if(l&F.LAST_BOUNDARY&&r===HYPHEN)o=S.END,l=0;elseif(!(l&F.LAST_BOUNDARY)&&r===LF)e=0,T("onPartBegin"),o=S.HEADER_FIELD_START;elsereturn;break}r!==h[e+2]&&(e=-2),r===h[e+2]&&e++;break;caseS.HEADER_FIELD_START:o=S.HEADER_FIELD,u("onHeaderField"),e=0;caseS.HEADER_FIELD:if(r===CR){i("onHeaderField"),o=S.HEADERS_ALMOST_DONE;break}if(e++,r===HYPHEN)break;if(r===COLON){if(e===1)return;L("onHeaderField",!0),o=S.HEADER_VALUE_START;break}if(P=lower(r),P<A||P>Z)return;break;caseS.HEADER_VALUE_START:if(r===SPACE)break;u("onHeaderValue"),o=S.HEADER_VALUE;caseS.HEADER_VALUE:r===CR&&(L("onHeaderValue",!0),T("onHeaderEnd"),o=S.HEADER_VALUE_ALMOST_DONE);break;caseS.HEADER_VALUE_ALMOST_DONE:if(r!==LF)return;o=S.HEADER_FIELD_START;break;caseS.HEADERS_ALMOST_DONE:if(r!==LF)return;T("onHeadersEnd"),o=S.PART_DATA_START;break;caseS.PART_DATA_START:o=S.PART_DATA,u("onPartData");caseS.PART_DATA:if(E=e,e===0){for(t+=m;t<O&&!(a[t]inH);)t+=b;t-=m,r=a[t]}if(e<h.length)h[e]===r?(e===0&&L("onPartData",!0),e++):e=0;elseif(e===h.length)e++,r===CR?l|=F.PART_BOUNDARY:r===HYPHEN?l|=F.LAST_BOUNDARY:e=0;elseif(e-1===h.length)if(l&F.PART_BOUNDARY){if(e=0,r===LF){l&=~F.PART_BOUNDARY,T("onPartEnd"),T("onPartBegin"),o=S.HEADER_FIELD_START;break}}elsel&F.LAST_BOUNDARY&&r===HYPHEN?(T("onPartEnd"),o=S.END,l=0):e=0;if(e>0)d[e-1]=r;elseif(E>0){constD=newUint8Array(d.buffer,d.byteOffset,d.byteLength);T("onPartData",0,E,D),E=0,u("onPartData"),t--}break;caseS.END:break;default:thrownewError(`Unexpected state entered: ${o}`)}L("onHeaderField"),L("onHeaderValue"),L("onPartData"),this.index=e,this.state=o,this.flags=l}end(){if(this.state===S.HEADER_FIELD_START&&this.index===0||this.state===S.PART_DATA&&this.index===this.boundary.length)this.onPartEnd();elseif(this.state!==S.END)thrownewError("MultipartParser.end(): stream ended unexpectedly")}}function_fileName(_){consta=_.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);if(!a)return;constt=a[2]||a[3]||"";letn=t.slice(t.lastIndexOf("\\")+1);returnn=n.replace(/%22/g,'"'),n=n.replace(/&#(\d{4});/g,(E,d)=>String.fromCharCode(d)),n}c(_fileName,"_fileName");asyncfunctiontoFormData(_,a){if(!/multipart/i.test(a))thrownewTypeError("Failed to fetch");constt=a.match(/boundary=(?:"([^"]+)"|([^;]+))/i);if(!t)thrownewTypeError("no or bad content-type header, no multipart boundary");constn=newMultipartParser(t[1]||t[2]);letE,d,h,H,e,o;constl=[],b=newnode.FormData,m=c(i=>{h+=u.decode(i,{stream:!0})},"onPartData"),O=c(i=>{l.push(i)},"appendToFile"),r=c(()=>{consti=newnode.File(l,o,{type:e});b.append(H,i)},"appendFileToFormData"),P=c(()=>{b.append(H,h)},"appendEntryToFormData"),u=newTextDecoder("utf-8");u.decode(),n.onPartBegin=function(){n.onPartData=m,n.onPartEnd=P,E="",d="",h="",H="",e="",o=null,l.length=0},n.onHeaderField=function(i){E+=u.decode(i,{stream:!0})},n.onHeaderValue=function(i){d+=u.decode(i,{stream:!0})},n.onHeaderEnd=function(){if(d+=u.decode(),E=E.toLowerCase(),E==="content-disposition"){consti=d.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);i&&(H=i[2]||i[3]||""),o=_fileName(d),o&&(n.onPartData=O,n.onPartEnd=r)}elseE==="content-type"&&(e=d);d="",E=""};forawait(constiof_)n.write(i);returnn.end(),b}c(toFormData,"toFormData"),exports.toFormData=toFormData;
@ -25,7 +25,7 @@ This document covers terminology, how the action works, general usage guidelines
## Terminology
[Pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#about-pull-requests) are proposed changes to a repository branch that can be reviewed by a repository's collaborators before being accepted or rejected.
[Pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#about-pull-requests) are proposed changes to a repository branch that can be reviewed by a repository's collaborators before being accepted or rejected.
A pull request references two branches:
@ -150,7 +150,7 @@ There are a number of workarounds with different pros and cons.
- Use the default `GITHUB_TOKEN` and allow the action to create pull requests that have no checks enabled. Manually close pull requests and immediately reopen them. This will enable `on: pull_request` workflows to run and be added as checks. To prevent merging of pull requests without checks erroneously, use [branch protection rules](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests).
- Create draft pull requests by setting the `draft: always-true` input, and configure your workflow to trigger `on: ready_for_review`. The workflow will run when users manually click the "Ready for review" button on the draft pull requests. If the pull request is updated by the action, the `always-true` mode ensures that the pull request will be converted back to a draft.
- Create draft pull requests by setting the `draft: always-true` input, and configure your workflow to trigger `ready_for_review` in `on: pull_request`. The workflow will run when users manually click the "Ready for review" button on the draft pull requests. If the pull request is updated by the action, the `always-true` mode ensures that the pull request will be converted back to a draft.
- Use a [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) created on an account that has write access to the repository that pull requests are being created in. This is the standard workaround and [recommended by GitHub](https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow). It's advisable to use a dedicated [machine account](https://docs.github.com/en/github/site-policy/github-terms-of-service#3-account-requirements) that has collaborator access to the repository, rather than creating a PAT on a personal user account. Also note that because the account that owns the PAT will be the creator of pull requests, that user account will be unable to perform actions such as request changes or approve the pull request.
@ -197,8 +197,9 @@ Checking out a branch from a different repository from where the workflow is exe
Allowing the action to push with a configured deploy key will trigger `on: push` workflows. This makes it an alternative to using a PAT to trigger checks for pull requests.
> [!NOTE]
> You cannot use deploy keys alone to [create a pull request in a remote repository](#creating-pull-requests-in-a-remote-repository) because then using a PAT would become a requirement.
> - You cannot use deploy keys alone to [create a pull request in a remote repository](#creating-pull-requests-in-a-remote-repository) because then using a PAT would become a requirement.
> This method only makes sense if creating a pull request in the repository where the workflow is running.
> - You cannot use deploy keys with [commit signature verification for bots](#commit-signature-verification-for-bots) (`sign-commits: true`).
How to use SSH (deploy keys) with create-pull-request action:
@ -231,7 +232,7 @@ It will use their own fork to push code and create the pull request.
1. Create a new GitHub user and login.
2. Fork the repository that you will be creating pull requests in.
3. Create a Classic [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) with `repo` scope.
3. Create a Classic [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) with `repo` and `workflow` scopes.
4. Logout and log back into your main user account.
5. Add a secret to your repository containing the above PAT.
6. As shown in the following example workflow, set the `push-to-fork` input to the full repository name of the fork.
@ -303,7 +304,7 @@ GitHub App generated tokens can be configured with fine-grained permissions and
- Uncheck `Active` under `Webhook`. You do not need to enter a `Webhook URL`.
- Under `Repository permissions: Contents` select `Access: Read & write`.
- Under `Repository permissions: Workflows` select `Access: Read-only`.
- Under `Repository permissions: Workflows` select `Access: Read & write`.
- **NOTE**: Only needed if pull requests could contain changes to Actions workflows.
- Under `Organization permissions: Members` select `Access: Read-only`.
- **NOTE**: Only needed if you would like add teams as reviewers to PRs.
@ -373,7 +374,7 @@ The action supports two methods to sign commits, [commit signature verification
The action can sign commits as `github-actions[bot]` when using the repository's default `GITHUB_TOKEN`, or your own bot when using [GitHub App tokens](#authenticating-with-github-app-generated-tokens).
> [!IMPORTANT]
> [!IMPORTANT]
> - When setting `sign-commits: true` the action will ignore the `committer` and `author` inputs.
> - If you attempt to use a [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) the action will create the pull request, but commits will *not* be signed. Commit signing is only supported with bot generated tokens.
> - The GitHub API has a 40MiB limit when creating git blobs. An error will be raised if there are files in the pull request larger than this. If you hit this limit, use [GPG commit signature verification](#gpg-commit-signature-verification) instead.
- [Show an annotation message for a created pull request](#show-an-annotation-message-for-a-created-pull-request)
## Use case: Create a pull request to update X on push
@ -324,7 +324,7 @@ jobs:
### Keep a fork up-to-date with its upstream
This example is designed to be run in a seperate repository from the fork repository itself.
This example is designed to be run in a separate repository from the fork repository itself.
The aim of this is to prevent committing anything to the fork's default branch would cause it to differ from the upstream.
In the following example workflow, `owner/repo` is the upstream repository and `fork-owner/repo` is the fork. It assumes the default branch of the upstream repository is called `main`.
@ -612,3 +612,30 @@ To enable step debug logging set the secret `ACTIONS_STEP_DEBUG` to `true` in th
MATRIX_CONTEXT:${{ toJson(matrix) }}
run:echo "$MATRIX_CONTEXT"
```
### Show an annotation message for a created pull request
Showing an annotation message for a created or updated pull request allows you to confirm the pull request easily, such as by visiting the link. This can be achieved by adding a step that uses the [`notice` workflow command](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions?tool=bash#setting-a-notice-message).
In this example, when a pull request is created, you will be able to see the following message on an action run page (e.g., `/actions/runs/12812393039`):
```
https://github.com/peter-evans/create-pull-request/pull/1 was created.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.