Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitHub upload using GraphQL #882

Merged
merged 51 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8b05e98
add new graphql
samchungy May 29, 2022
d5161b7
make syntax nicer
samchungy May 29, 2022
3c875e0
use input type
samchungy May 29, 2022
f5aa05c
try updating local
samchungy May 29, 2022
187df3e
try updating local
samchungy May 29, 2022
c6cb148
refactor
samchungy May 29, 2022
cc134e8
remove nullish
samchungy May 29, 2022
b9632c3
change update local logic
samchungy May 29, 2022
6a3136f
reuse file changes
samchungy May 29, 2022
cf59169
add some tests
samchungy Jun 4, 2022
c6b054f
test log
samchungy Jun 4, 2022
fb0a9a8
fix-tests
samchungy Jun 4, 2022
e23bc52
add-doco
samchungy Jun 4, 2022
a4d95c7
remove run command
samchungy Jun 4, 2022
bc5272c
Merge branch 'master' into graphql-commit
samchungy Jun 4, 2022
5e9fabf
use fs-extra
samchungy Jun 4, 2022
74fd6c9
Merge branch 'graphql-commit' of github.com:seek-oss/skuba into graph…
samchungy Jun 4, 2022
38f3bef
add changelogs
samchungy Jun 4, 2022
0d2bf95
add beforeEach
samchungy Jun 4, 2022
03055af
remove reset
samchungy Jun 4, 2022
6c40f7f
set env var
samchungy Jun 4, 2022
17df7d8
fix env var
samchungy Jun 4, 2022
1bfb2e8
fix: correct bad copy pasta
samchungy Jun 4, 2022
318b5a6
nitpick doco
samchungy Jun 5, 2022
528d792
spelling
samchungy Jun 5, 2022
53e96bc
add better jsdoc
samchungy Jun 5, 2022
7e66e02
Update stale-forks-love.md
samchungy Jun 5, 2022
397d665
feat: add return type for no file changes
samchungy Jun 7, 2022
2a25f8b
declare graphql tag for prettier
samchungy Jun 7, 2022
e7bd4c2
change autofix
samchungy Jun 7, 2022
3f749b8
fix condition
samchungy Jun 7, 2022
2173fb1
Merge branch 'master' into graphql-commit
samchungy Jun 7, 2022
040e7c0
fix: get the commit oid
samchungy Jun 7, 2022
6f0b25d
add changeset
samchungy Jun 7, 2022
62c9517
add link to GitHub Autofixes
samchungy Jun 7, 2022
fc8e31d
Merge branch 'master' into graphql-commit
samchungy Jun 7, 2022
1ed15dd
Merge branch 'master' into graphql-commit
72636c Jun 10, 2022
3dbeb8a
Merge branch 'master' into graphql-commit
72636c Jun 15, 2022
fd2be9d
Merge branch 'master' into graphql-commit
72636c Jun 19, 2022
c18f55d
Apply suggestions from code review
72636c Jun 19, 2022
18268e3
Update docs/development-api/github.md
72636c Jun 20, 2022
25eba43
Apply suggestions from code review
72636c Jun 20, 2022
ce339b1
update names
samchungy Jun 21, 2022
76fd854
Remove explicit `graphql-tag` dep
72636c Jun 22, 2022
b4f8db7
Apply suggestions from code review
72636c Jun 22, 2022
cc8c4df
Tweak doco
72636c Jun 22, 2022
ac01f19
Tweak error message
72636c Jun 22, 2022
681a7bb
Make warning more verbose
72636c Jun 22, 2022
60584fa
Merge branch 'master' into graphql-commit
72636c Jun 22, 2022
13fd824
Use "upload" instead of "push"
72636c Jun 22, 2022
4104f25
Merge branch 'master' into graphql-commit
72636c Jun 22, 2022
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
5 changes: 5 additions & 0 deletions .changeset/stale-forks-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'skuba': minor
---

Git: Add [fastForwardBranch](https://seek-oss.github.io/skuba/docs/development-api/git.html#fastForwardBranch) function
7 changes: 7 additions & 0 deletions .changeset/thin-carrots-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'skuba': minor
---

GitHub: Add functions to create and push verified commits using the GitHub GraphQL API

See our [GitHub API documentation](https://seek-oss.github.io/skuba/docs/development-api/github.html#commitAndPush) for more information.
5 changes: 5 additions & 0 deletions .changeset/unlucky-kings-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'skuba': patch
---

lint: Use GitHub GraphQL API to push verified autofix commits
3 changes: 3 additions & 0 deletions docs/cli/lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ you can limit this with the `--serial` flag.
| `--debug` | Enable debug console output (implies `--serial`) |
| `--serial` | Force serial execution of linting operations |

[GitHub autofixes] are enabled when CI and GitHub environment variables are present.

### Annotations

`skuba lint` can automatically emit annotations in CI.
Expand All @@ -74,6 +76,7 @@ you can limit this with the `--serial` flag.
[eslint-config-seek]: https://github.com/seek-oss/eslint-config-seek
[eslint]: https://eslint.org/
[github annotations]: ../deep-dives/github.md#github-annotations
[github autofixes]: ../deep-dives/github.md#github-autofixes
[prescribes eslint]: https://tech-strategy.ssod.skinfra.xyz/docs/v1/technology.html#typescript
[prettier]: https://prettier.io/
[tsc]: https://www.typescriptlang.org/docs/handbook/compiler-options.html
18 changes: 18 additions & 0 deletions docs/development-api/git.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@ const currentBranch = Git.currentBranch({ dir });

---

## fastForwardBranch

Fast forwards the specified `ref` from the remote to the local Git repository
72636c marked this conversation as resolved.
Show resolved Hide resolved

Currently, only GitHub app tokens are supported as an auth mechanism.

```typescript
import { Git } from 'skuba';

await Git.fastForwardBranch({
auth: { type: 'gitHubApp' },
dir,
ref: 'branch-name',
});
```

---

## getChangedFiles

Returns all the files which have been added, modified or deleted in the working directory of the local Git repository since the last commit.
Expand Down
65 changes: 65 additions & 0 deletions docs/development-api/github.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,53 @@ const buildName = GitHub.buildNameFromEnvironment();

---

## commitAndPush

Commits and pushes file changes from the local workspace to a specified GitHub branch.

Commits pushed using this method appear verified on GitHub.

```typescript
import { GitHub } from 'skuba';

const commitId = await GitHub.commitAndPush({
dir: './',
branch: 'some-branch',
fileChanges: {
additions: [{ contents: '', path: 'another-path' }],
deletions: [{ path: 'some-path' }],
},
messageHeadline: 'some-commit',
messageBody: 'extra-body',
updateLocal: true, // Updates the local Git repository to reflect the new remote branch state
});
```

---

## commitAndPushAllChanges

Retrieves all file changes from the local Git repository using [getChangedFiles],
then commits and pushes the changes to a specified GitHub branch using [commitAndPush](#commitandpush).

Commits pushed using this method appear verified on GitHub.

`undefined` is returned instead of a commit ID when there are no changes to push.

```typescript
import { GitHub } from 'skuba';

const commitId = await GitHub.commitAndPushAllChanges({
dir: './',
branch: 'some-branch',
messageHeadline: 'some-commit',
messageBody: 'extra-body',
updateLocal: true, // Updates the local Git repository to reflect the new remote branch state
});
```

---

## createCheckRun

Asynchronously creates a GitHub [check run] with annotations.
Expand Down Expand Up @@ -119,5 +166,23 @@ await GitHub.putIssueComment({

---

## mapChangedFilesToFileChanges
Copy link
Member

Choose a reason for hiding this comment

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

Given this is an I/O operation, I wonder if the verb should here be read or load?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I think that makes sense, when I first started this I thought it was going to be a simple map.


Maps changed files from [getChangedFiles] to GitHub GraphQL [file changes]
72636c marked this conversation as resolved.
Show resolved Hide resolved

```typescript
import { GitHub } from 'skuba';

const fileChanges = await GitHub.mapChangedFilesToFileChanges([
{ path: 'added-path', state: 'added' },
{ path: 'modified-path', state: 'modified' },
{ path: 'delete-path', state: 'deleted' },
]);
```

---

[check run]: https://docs.github.com/en/rest/reference/checks#runs
[file changes]: https://docs.github.com/en/graphql/reference/input-objects#filechanges
72636c marked this conversation as resolved.
Show resolved Hide resolved
[getchangedfiles]: ./git.md#getchangedfiles
[github guide]: ../deep-dives/github.md
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"url": "https://github.com/seek-oss/skuba/issues"
},
"dependencies": {
"@octokit/graphql": "^4.8.0",
"@octokit/graphql-schema": "^10.73.0",
"@octokit/rest": "^18.12.0",
"@octokit/types": "^6.34.0",
"@types/jest": "^28.0.0",
Expand Down Expand Up @@ -63,6 +65,7 @@
"@types/supertest": "2.0.12",
"enhanced-resolve": "5.9.3",
"express": "4.18.1",
"graphql-tag": "2.12.6",
72636c marked this conversation as resolved.
Show resolved Hide resolved
"jsonfile": "6.1.0",
"koa": "2.13.4",
"memfs": "3.4.4",
Expand Down
1 change: 1 addition & 0 deletions src/api/git/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export { getChangedFiles } from './getChangedFiles';
export { getHeadCommitId, getHeadCommitMessage } from './log';
export { getOwnerAndRepo } from './remote';
export { push } from './push';
export { fastForwardBranch } from './pull';
export { reset } from './reset';
42 changes: 42 additions & 0 deletions src/api/git/pull.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import git from 'isomorphic-git';

import { fastForwardBranch } from './pull';

jest.mock('isomorphic-git');

afterEach(jest.resetAllMocks);

describe('fastForwardBranch', () => {
it('propagates props to isomorphic-git', async () => {
jest
.mocked(git.listRemotes)
.mockResolvedValue([
{ remote: 'origin', url: '[email protected]:seek-oss/skuba.git' },
]);

await fastForwardBranch({
auth: { token: 'abc', type: 'gitHubApp' },
dir: '/workdir/skuba',
ref: 'c'.repeat(40),
remoteRef: 'feature-a',
});

expect(git.fastForward).toHaveBeenCalledTimes(1);
expect(jest.mocked(git.fastForward).mock.calls[0][0]).toMatchInlineSnapshot(
{ http: expect.any(Object), fs: expect.any(Object) },
`
Object {
"dir": "/workdir/skuba",
"fs": Any<Object>,
"http": Any<Object>,
"onAuth": [Function],
"ref": "cccccccccccccccccccccccccccccccccccccccc",
"remote": undefined,
"remoteRef": "feature-a",
"singleBranch": true,
"url": "https://github.com/seek-oss/skuba",
}
`,
);
});
});
75 changes: 75 additions & 0 deletions src/api/git/pull.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import fs from 'fs-extra';
import git from 'isomorphic-git';
import http from 'isomorphic-git/http/node';

import { apiTokenFromEnvironment } from '../github/environment';

import { getOwnerAndRepo } from './remote';

/**
* Use a GitHub app token to auth the Git push.
*
* This defaults to the `GITHUB_API_TOKEN` and `GITHUB_TOKEN` environment
* variables if `token` is not provided.
*/
interface GitHubAppAuth {
type: 'gitHubApp';
token?: string;
}

interface PullParameters {
/**
* The auth mechanism for the push.
*
* Currently, only GitHub app tokens are supported.
*/
auth: GitHubAppAuth;

dir: string;

/**
* The branch to merge into
72636c marked this conversation as resolved.
Show resolved Hide resolved
*/
ref: string;

remote?: string;

/**
* The destination branch or tag on the remote.
72636c marked this conversation as resolved.
Show resolved Hide resolved
*
* This defaults to `ref`.
*/
remoteRef?: string;
}

/**
* Fast forwards the local branch to the remote state
72636c marked this conversation as resolved.
Show resolved Hide resolved
*/
export const fastForwardBranch = async ({
auth,
dir,
ref,
remote,
remoteRef,
}: PullParameters) => {
const { owner, repo } = await getOwnerAndRepo({ dir });

const url = `https://github.com/${encodeURIComponent(
owner,
)}/${encodeURIComponent(repo)}`;

return git.fastForward({
onAuth: () => ({
username: 'x-access-token',
password: auth.token ?? apiTokenFromEnvironment(),
}),
dir,
fs,
http,
ref,
remote,
remoteRef,
url,
singleBranch: true,
});
};
5 changes: 5 additions & 0 deletions src/api/github/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ export { createCheckRun } from './checkRun';
export { enabledFromEnvironment } from './environment';
export { getPullRequestNumber } from './pullRequest';
export { putIssueComment } from './issueComment';
export {
commitAndPush,
commitAndPushAllChanges,
mapChangedFilesToFileChanges,
} from './push';
Loading