Skip to content

Commit 165c6cb

Browse files
authored
Rename APIs and export types (#117)
* Rename APIs and export types * Remove Octokit export
1 parent 67853bf commit 165c6cb

11 files changed

Lines changed: 244 additions & 266 deletions

File tree

.changeset/sunny-nights-heal.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@changesets/ghcommit": major
3+
---
4+
5+
Rename public APIs and export types. Note that the existing changelog may still reference the old names, but the new names should be used instead.
6+
7+
- `commitFilesFromBase64` -> `commitChanges`
8+
- `commitChangesFromRepo` -> `commitChangesSinceBase`

README.md

Lines changed: 47 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
> [!IMPORTANT]
44
> This is the development branch for `@changesets/ghcommit` v3. For the v2 code, check out the [maintenance/v2](https://github.com/changesets/ghcommit/tree/maintenance/v2) branch.
55
6-
[![View on NPM](https://badgen.net/npm/v/@changesets/ghcommit)](https://www.npmjs.com/package/@changesets/ghcommit)
6+
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/version/@changesets/ghcommit?name=true)](https://npmx.dev/package/@changesets/ghcommit)
7+
[![View changelog](https://npmx.dev/api/registry/badge/version/@changesets/ghcommit?color=229fe4&value=View+changelog&label=+)](./CHANGELOG.md)
78

8-
NPM / TypeScript package to commit changes GitHub repositories using the GraphQL API.
9+
Commit file changes to GitHub repositories with the GitHub API.
910

1011
## Why?
1112

1213
- **Simplified GPG Signing:**
1314

14-
If you or your organisation has strict requirements
15-
around requiring signed commits (i.e. via Branch Protection or Repo Rulesets), then this can make integrating CI workflows or applications that are designed to make changes to your repos quite difficult. This is because you will need to manage your own GPG keys, assign them to machine accounts (which also means it doesn't work with GitHub Apps), and securely manage and rotate them.
15+
If you or your organization has strict requirements around requiring signed commits (i.e. via Branch Protection or Repo Rulesets), then this can make integrating CI workflows or applications that are designed to make changes to your repos quite difficult. This is because you will need to manage your own GPG keys, assign them to machine accounts (which also means it doesn't work with GitHub Apps), and securely manage and rotate them.
1616

1717
Instead of doing this, if you use the GitHub API to make changes to files (such as what happens when making changes to files directly in the web UI), then GitHub's internal GPG key is used, and commits are all signed and associated with the user of the access token that was used.
1818

19-
(And this also works with GitHub Apps too, including the GitHub Actions app).
19+
(And this also works with GitHub Apps too).
2020

21-
![](docs/verified.png)
21+
<img src="docs/verified.png" alt="Verified commit" height="182px" />
2222

23-
This library has primarily been designed for use in custom Node GitHub Actions, but can be used in any Node.js or JavaScript project that needs to directly modify files in GitHub repositories.
23+
This library has primarily been designed for use in GitHub Actions, but can be used in any Node.js or JavaScript project that needs to directly modify files in GitHub repositories.
2424

2525
- **Simplified Git Config:**
2626

@@ -32,15 +32,17 @@ NPM / TypeScript package to commit changes GitHub repositories using the GraphQL
3232

3333
### Installation
3434

35-
Install using your favourite package manager:
35+
Install using your favorite package manager:
3636

37-
```
37+
```bash
3838
pnpm install @changesets/ghcommit
3939
```
4040

41-
### Usage in github actions
41+
### Octokit
42+
43+
The library requires an [Octokit](https://github.com/octokit/octokit.js) client to call the GitHub APIs. It requires the `@octokit/core`, `@octokit/plugin-rest-endpoint-methods`, and `@octokit/plugin-paginate-rest` packages to be set up in order to work.
4244

43-
All functions in this library that interact with the GitHub API require an octokit client that can execute GraphQL. If you are writing code that is designed to be run from within a GitHub Action, this can be done using the `@actions/github` library:
45+
If you're running this in GitHub Actions, this can be done using the `@actions/github` library:
4446

4547
```ts
4648
import { getOctokit } from "@actions/github";
@@ -50,71 +52,30 @@ const octokit = getOctokit(process.env.GITHUB_TOKEN);
5052

5153
## API
5254

53-
All the functions below accept a single object as its argument, and share the following base arguments:
54-
55-
<!-- TODO: point to some generated docs instead of including a code snippet -->
55+
Check the respective JSDoc for the complete documentation.
5656

57-
```ts
58-
{
59-
octokit: GitHubClient;
60-
owner: string;
61-
repo: string;
62-
branch: string;
63-
/**
64-
* Push the commit even if the branch exists and does not match what was
65-
* specified as the base.
66-
*/
67-
force?: boolean;
68-
/**
69-
* The commit message
70-
*/
71-
message: string | CommitMessage;
72-
}
73-
```
74-
75-
### `commitFilesFromBase64`
57+
### `commitChanges`
7658

7759
> Works in Node.js and browsers
7860
79-
This function will add or delete specific files from a repository's branch based on the given `fileChanges` argument.
80-
81-
In addition to `CommitFilesBasedArgs`, this function has the following arguments:
82-
83-
```ts
84-
{
85-
/**
86-
* The current branch, tag or commit that the new branch should be based on.
87-
*/
88-
base: GitBase;
89-
/**
90-
* The file paths, relative to git root, to add or delete from the branch on GitHub.
91-
*/
92-
fileChanges: {
93-
/**
94-
* File paths, relative to git root, to add to the repo. Content is a base64-encoded string.
95-
*/
96-
additions?: { path: string; content: string }[];
97-
/**
98-
* File paths, relative to git root, to remove from the repo.
99-
*/
100-
deletions?: { path: string }[];
101-
};
102-
}
103-
```
61+
Commit file changes to a branch using the GitHub API.
10462

10563
Example:
10664

10765
```ts
10866
import fs from "node:fs/promises";
10967
import { context, getOctokit } from "@actions/github";
110-
import { commitFilesFromBase64 } from "@changesets/ghcommit";
68+
import { commitChanges } from "@changesets/ghcommit";
11169

11270
const octokit = getOctokit(process.env.GITHUB_TOKEN);
71+
const owner = context.repo.owner;
72+
const repo = context.repo.repo;
11373

114-
// Commit the changes to README.md based on the main branch
115-
await commitFilesFromBase64({
74+
// Commit the changes to README.md and delete the lockfile based on the main branch
75+
await commitChanges({
11676
octokit,
117-
...context.repo,
77+
owner,
78+
repo,
11879
branch: "new-branch-to-create",
11980
message: "[chore] do something",
12081
base: {
@@ -124,110 +85,66 @@ await commitFilesFromBase64({
12485
additions: [
12586
{ path: "README.md", content: await fs.readFile("README.md", "base64") },
12687
],
88+
deletions: [{ path: "package-lock.json" }],
12789
},
12890
});
12991
```
13092

131-
### `commitChangesFromRepo`
93+
### `commitChangesSinceBase`
13294

13395
> Works in Node.js only
13496
135-
This function will take an existing repository on your filesystem (defaulting to the current working directory). This function is good to use if you're usually working within the context of a git repository, such as after running `@actions/checkout` in github actions.
136-
137-
In addition to `CommitFilesBasedArgs`, this function has the following arguments:
97+
Commit file changes since a local git base (defaults to HEAD). This executes the `git` command to determine the changes and then uses `commitChanges` to commit them to the given branch.
13898

139-
```ts
140-
{
141-
/**
142-
* The directory used to find the repository root,
143-
* and search for changed files to commit.
144-
*
145-
* Any files that have been changed outside of this directory will be ignored.
146-
*/
147-
cwd: string;
148-
/**
149-
* The base commit to build your changes on-top of
150-
*
151-
* @default HEAD
152-
*/
153-
base?: {
154-
commit: string;
155-
};
156-
/**
157-
* Don't require {@link cwd} to be the root of the repository,
158-
* and use it as a starting point to recursively search for the `.git`
159-
* directory in parent directories.
160-
*
161-
* @default true
162-
*/
163-
recursivelyFindRoot?: boolean;
164-
/**
165-
* An optional function that can be used to filter which files are included
166-
* in the commit. True should be returned for files that should be included.
167-
*
168-
* By default, all files are included.
169-
*/
170-
filterFiles?: (file: string) => boolean;
171-
}
172-
```
99+
The default HEAD base includes all uncommitted changes since the last commit. If previous commits have been made locally and not pushed, you need to set `base` to the last commit that is known to be in the remote repository.
173100

174101
Example:
175102

176103
```ts
177104
import { context, getOctokit } from "@actions/github";
178-
import { commitChangesFromRepo } from "@changesets/ghcommit";
105+
import { commitChangesSinceBase } from "@changesets/ghcommit";
179106

180107
const octokit = getOctokit(process.env.GITHUB_TOKEN);
108+
const owner = context.repo.owner;
109+
const repo = context.repo.repo;
181110

182-
// Commit & push the files from the current directory
183-
// e.g. if you're just using @ations/checkout
184-
await commitChangesFromRepo({
111+
// Commit the file changes from the current directory
112+
await commitChangesSinceBase({
185113
octokit,
186-
...context.repo,
114+
owner,
115+
repo,
187116
branch: "new-branch-to-create",
188117
message: "[chore] do something",
189118
cwd: process.cwd(),
190119
});
191120

192-
// Commit & push the files from a specific directory
193-
// where we've cloned a repo, and made changes to files
194-
await commitChangesFromRepo({
121+
// Commit the file changes from a different directory (and git repo)
122+
await commitChangesSinceBase({
195123
octokit,
196124
owner: "my-org",
197-
repository: "my-repo",
198-
branch: "another-new-branch-to-create",
199-
message: "[chore] do something else\n\nsome more details",
125+
repo: "my-repo",
126+
branch: "new-branch-to-create",
127+
message: "[chore] do something else",
200128
cwd: "/tmp/some-repo",
201129
});
202130

203-
// Commit & push the files from the current directory,
204-
// but ensure changes from any locally-made commits are also included
205-
await commitChangesFromRepo({
131+
// Commit the file changes including commits added since the workflow run
132+
await commitChangesSinceBase({
206133
octokit,
207-
...context.repo,
208-
branch: "another-new-branch-to-create",
209-
message: {
210-
headline: "[chore] do something else",
211-
body: "some more details",
212-
},
134+
owner,
135+
repo,
136+
branch: "new-branch-to-create",
137+
message: "[chore] do something else",
213138
cwd: process.cwd(),
214139
base: {
215-
// This will be the original sha from the workflow run,
216-
// even if we've made commits locally
217-
commit: context.sha,
140+
commit: context.sha, // The initial SHA of the workflow run
218141
},
219142
});
220143
```
221144

222145
## Known Limitations
223146

224-
Due to using the GitHub API to make changes to repository contents,
225-
there are some things it's not possible to commit,
226-
and where using the Git CLI is still required.
227-
228-
- Executable files
229-
- Symbolic Links
230-
- Submodule changes
147+
The GitHub API does not allow committing executable files, symbolic links, or submodule changes. If you need to commit any of these types of files, you will need to use the Git CLI instead.
231148

232149
## Other Tools / Alternatives
233150

src/core.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ import {
33
createCommitOnBranchQuery,
44
getRepositoryMetadata,
55
} from "./github/graphql/queries.ts";
6-
import type {
7-
CommitFilesFromBase64Args,
8-
CommitFilesResult,
9-
} from "./interface.ts";
6+
import type { CommitChangesOptions, CommitChangesResult } from "./types.ts";
107
import { normalizeCommitMessage, resolveGitRef } from "./utils.ts";
118

129
type CreateCommit = (
1310
refId: string,
1411
branch: string,
1512
) => Promise<{ commitSha: string }>;
1613

17-
export async function commitFilesFromBase64({
14+
/**
15+
* Commit file changes to a branch using the GitHub API.
16+
*
17+
* Works in Node.js and browsers.
18+
*/
19+
export async function commitChanges({
1820
octokit,
1921
owner,
2022
repo,
@@ -23,7 +25,7 @@ export async function commitFilesFromBase64({
2325
force = false,
2426
message,
2527
fileChanges,
26-
}: CommitFilesFromBase64Args): Promise<CommitFilesResult> {
28+
}: CommitChangesOptions): Promise<CommitChangesResult> {
2729
const baseRef = resolveGitRef(base);
2830

2931
const info = await getRepositoryMetadata(octokit, {
@@ -166,7 +168,7 @@ async function createOrForceUpdateTemporaryBranch({
166168
repo,
167169
tempBranch,
168170
baseSha,
169-
}: Pick<CommitFilesFromBase64Args, "octokit" | "owner" | "repo"> & {
171+
}: Pick<CommitChangesOptions, "octokit" | "owner" | "repo"> & {
170172
tempBranch: string;
171173
baseSha: string;
172174
}) {

src/git.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
import fs from "node:fs/promises";
22
import path from "path";
33
import { exec } from "tinyexec";
4-
import { commitFilesFromBase64 } from "./core.ts";
4+
import { commitChanges } from "./core.ts";
55
import type {
6-
CommitChangesFromRepoArgs,
7-
CommitFilesFromBase64Args,
8-
CommitFilesResult,
9-
} from "./interface.ts";
6+
CommitChangesOptions,
7+
CommitChangesSinceBaseOptions,
8+
CommitChangesResult,
9+
} from "./types.ts";
1010
import { resolveGitRef } from "./utils.ts";
1111

12-
export async function commitChangesFromRepo({
12+
/**
13+
* Commit file changes since a local git base (defaults to HEAD). This executes
14+
* the `git` command to determine the changes and then uses {@link commitChanges}
15+
* to commit them to the given branch.
16+
*
17+
* The default HEAD base includes all uncommitted changes since the last commit.
18+
* If previous commits have been made locally and not pushed, you need to set `base
19+
* to the last commit that is known to be in the remote repository.
20+
*
21+
* Works in Node.js only.
22+
*/
23+
export async function commitChangesSinceBase({
1324
cwd: workingDirectory,
1425
recursivelyFindRoot = true,
1526
filterFiles,
1627
...otherArgs
17-
}: CommitChangesFromRepoArgs): Promise<CommitFilesResult> {
28+
}: CommitChangesSinceBaseOptions): Promise<CommitChangesResult> {
1829
const ref = resolveGitRef(otherArgs.base ?? { commit: "HEAD" });
1930
const cwd = path.resolve(workingDirectory);
2031
const repoRoot = recursivelyFindRoot ? await findGitRoot(cwd) : cwd;
@@ -24,7 +35,7 @@ export async function commitChangesFromRepo({
2435
throw new Error(`Could not determine sha for ref ${ref}`);
2536
}
2637

27-
return await commitFilesFromBase64({
38+
return await commitChanges({
2839
...otherArgs,
2940
fileChanges: await getFileChanges(
3041
workingDirectory,
@@ -43,17 +54,17 @@ export async function getFileChanges(
4354
cwd: string,
4455
repoRoot: string,
4556
ref: string,
46-
filterFiles?: CommitChangesFromRepoArgs["filterFiles"],
47-
): Promise<CommitFilesFromBase64Args["fileChanges"]> {
57+
filterFiles?: CommitChangesSinceBaseOptions["filterFiles"],
58+
): Promise<CommitChangesOptions["fileChanges"]> {
4859
/**
4960
* The directory to add files from. This is relative to the repository
5061
* root, and is used to filter files.
5162
*/
5263
const relativeStartDirectory =
5364
cwd === repoRoot ? null : path.relative(repoRoot, cwd) + "/";
5465

55-
const additions: CommitFilesFromBase64Args["fileChanges"]["additions"] = [];
56-
const deletions: CommitFilesFromBase64Args["fileChanges"]["deletions"] = [];
66+
const additions: CommitChangesOptions["fileChanges"]["additions"] = [];
67+
const deletions: CommitChangesOptions["fileChanges"]["deletions"] = [];
5768

5869
const addPath = async (filePath: string) => {
5970
if (

0 commit comments

Comments
 (0)