Skip to content

Commit 5f45f18

Browse files
committed
added linting to the action (#49)
Added eslint and prettier and added the step of running the linter on pull requests Closes #47
1 parent 7510431 commit 5f45f18

File tree

14 files changed

+192
-193
lines changed

14 files changed

+192
-193
lines changed

.eslintrc.cjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const { getConfiguration } = require("opstooling-js-style/src/eslint/configuration");
2+
3+
const tsConfParams = { rootDir: __dirname };
4+
5+
const conf = getConfiguration({ typescript: tsConfParams });
6+
7+
module.exports = conf;

.github/workflows/javascript-test.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ jobs:
1212
with:
1313
node-version: 18
1414
- name: Install dependencies
15-
run: yarn install --immutable
15+
run: yarn install --frozen-lockfile
1616
- name: Run tests
1717
run: yarn test
18+
- name: Run lint
19+
run: yarn lint
1820
- name: Build the project
1921
run: yarn build

.prettierrc.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("opstooling-js-style/src/prettier/configuration")

jest.config.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
2-
preset: "ts-jest",
3-
testEnvironment: "node",
4-
testMatch: ["<rootDir>/src/test/**/*.test.ts"]
2+
preset: "ts-jest",
3+
testEnvironment: "node",
4+
testMatch: ["<rootDir>/src/test/**/*.test.ts"],
5+
moduleNameMapper: { "^src/(.*)$": `${process.cwd()}/src/$1` },
56
};

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
"typecheck": "tsc --noEmit",
1717
"fix:eslint": "eslint --fix",
1818
"fix:prettier": "prettier --write",
19-
"fix": "yarn fix:eslint '{*,**/*}.{cjs,ts}' && yarn fix:prettier '{*,**/*}.json'",
19+
"fix": "yarn fix:eslint '{*,**/*}.ts' && yarn fix:prettier '{*,**/*}.json'",
2020
"prettier": "prettier --check --loglevel silent '{*,**/*}.{json,html}'",
21-
"eslint": "eslint --quiet '{*,**/*}.{cjs,ts}'",
21+
"eslint": "eslint --quiet '{*,**/*}.ts'",
2222
"lint": "yarn eslint && yarn prettier"
2323
},
2424
"dependencies": {
@@ -30,7 +30,7 @@
3030
"@types/jest": "^29.2.5",
3131
"jest": "^29.3.1",
3232
"jest-mock-extended": "^3.0.1",
33-
"opstooling-js-style": "https://github.com/paritytech/opstooling-js-style#8578c0d55043e4e3db94f7fdf8b698bc4a86e58d",
33+
"opstooling-js-style": "https://github.com/paritytech/opstooling-js-style#c298d0f732d93712e4397fd53baa3317a3022c8c",
3434
"ts-jest": "^29.0.5",
3535
"typescript": "^4.9.4"
3636
}

src/github/CoreLogger.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import * as core from "@actions/core";
2+
23
import { ILogger } from "./types";
34

45
/** Implementation using the logger type from @actions/core */
56
export class CoreLogger implements ILogger {
6-
info(message: string): void {
7-
core.info(message);
8-
}
9-
warning(message: string): void {
10-
core.warning(message);
11-
}
12-
error(message: string | Error): void {
13-
core.error(message);
14-
}
15-
debug(message: string): void {
16-
core.debug(message);
17-
}
18-
notice(message: string): void {
19-
core.notice(message);
20-
}
21-
7+
info(message: string): void {
8+
core.info(message);
9+
}
10+
warning(message: string): void {
11+
core.warning(message);
12+
}
13+
error(message: string | Error): void {
14+
core.error(message);
15+
}
16+
debug(message: string): void {
17+
core.debug(message);
18+
}
19+
notice(message: string): void {
20+
core.notice(message);
21+
}
2222
}

src/github/issueKit.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import { GitHub } from "@actions/github/lib/utils";
2-
import { Octokit } from "@octokit/rest";
3-
import { IIssues, Issue, Repository } from "./types";
4-
52

3+
import { IIssues, Issue, Repository } from "./types";
64

75
export class IssueApi implements IIssues {
8-
/** Requires permissions to the repository with access to the repo */
9-
constructor(private readonly octokit: InstanceType<typeof GitHub>, private readonly repoData: Repository) {
10-
}
6+
/** Requires permissions to the repository with access to the repo */
7+
constructor(private readonly octokit: InstanceType<typeof GitHub>, private readonly repoData: Repository) {}
118

12-
async getIssueState(issueId: number): Promise<"open" | "closed"> {
13-
const { owner, repo } = this.repoData;
14-
const issueData = await this.octokit.rest.issues.get({ repo, owner, issue_number: issueId });
15-
return issueData.data.state === "open" ? "open" : "closed";
16-
}
9+
async getIssueState(issueId: number): Promise<"open" | "closed"> {
10+
const { owner, repo } = this.repoData;
11+
const issueData = await this.octokit.rest.issues.get({ repo, owner, issue_number: issueId });
12+
return issueData.data.state === "open" ? "open" : "closed";
13+
}
1714

18-
async getAllIssuesId(excludeClosed: boolean): Promise<Issue[]> {
19-
const allIssues = await this.octokit.rest.issues.listForRepo({ ...this.repoData, state: excludeClosed ? "open" : "all" });
20-
return allIssues.data;
21-
}
15+
async getAllIssuesId(excludeClosed: boolean): Promise<Issue[]> {
16+
const allIssues = await this.octokit.rest.issues.listForRepo({
17+
...this.repoData,
18+
state: excludeClosed ? "open" : "all",
19+
});
20+
return allIssues.data;
21+
}
2222
}

src/github/projectKit.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { graphql } from "@octokit/graphql";
2+
23
import { ILogger, IProjectApi, Issue, Repository } from "./types";
34

45
interface ProjectData {
@@ -14,29 +15,27 @@ interface ProjectData {
1415
};
1516
};
1617
};
17-
};
18+
}
1819

1920
interface CreatedProjectItemForIssue {
2021
addProjectNextItem: { projectNextItem: { id: string } };
21-
};
22-
22+
}
2323

2424
/**
2525
* Instance that manages the GitHub's project api
2626
* ? Octokit.js doesn't support Project v2 API yet so we need to use graphQL
2727
* Used this blog post as a reference for the queries: https://www.cloudwithchris.com/blog/automate-adding-gh-issues-projects-beta/
2828
*/
2929
export class ProjectKit implements IProjectApi {
30-
3130
private projectNodeId: string | null = null;
3231

3332
/** Requires an instance with a PAT with the 'write:org' permission enabled */
3433
constructor(
3534
private readonly gql: typeof graphql,
3635
private readonly repoData: Repository,
3736
private readonly projectNumber: number,
38-
private readonly logger: ILogger) {
39-
}
37+
private readonly logger: ILogger,
38+
) {}
4039

4140
/* changeIssueStateInProject(issueCardId: number, state: "todo" | "in progress" | "blocked" | "done"): Promise<void> {
4241
return this.gql(
@@ -99,13 +98,13 @@ export class ProjectKit implements IProjectApi {
9998
}
10099

101100
// step three
102-
updateProjectNextItemField(
101+
async updateProjectNextItemField(
103102
project: string,
104103
item: string,
105104
targetField: string,
106105
targetFieldValue: string,
107-
) {
108-
this.gql(
106+
): Promise<void> {
107+
await this.gql(
109108
`
110109
mutation (
111110
$project: ID!
@@ -129,7 +128,7 @@ export class ProjectKit implements IProjectApi {
129128
);
130129
}
131130

132-
async assignIssueToProject(issue: Issue, projectId: string) {
131+
async assignIssueToProject(issue: Issue, projectId: string): Promise<boolean> {
133132
const migration = await this.gql<CreatedProjectItemForIssue>(
134133
`
135134
mutation($project: ID!, $issue: ID!) {
@@ -152,7 +151,7 @@ export class ProjectKit implements IProjectApi {
152151

153152
this.logger.info(`Syncing issue #${issue.number} for ${this.projectNumber}`);
154153

155-
return this.assignIssueToProject(issue, projectId)
154+
return await this.assignIssueToProject(issue, projectId);
156155

157156
// TODO: Assign targetField
158157
}

src/github/types.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
1-
export type Repository = { owner: string, repo: string };
1+
export type Repository = { owner: string; repo: string };
22

33
export type Issue = { number: number; node_id: string };
44

55
export interface IProjectApi {
6-
/**
7-
* Assign an issue to a project
8-
* @param issueNodeId The issue node_id (which differs from the issue id)
9-
* @param projectId The project id (found in github.com/repo/projects/<ID>)
10-
*/
11-
assignIssue(issue: Issue): Promise<boolean>;
12-
// getProjectIdFromIssue(issueId: number): Promise<number>;
13-
// changeIssueStateInProject(issueId: number, state: "todo" | "in progress" | "blocked" | "done"): Promise<boolean>;
6+
/**
7+
* Assign an issue to a project
8+
* @param issueNodeId The issue node_id (which differs from the issue id)
9+
* @param projectId The project id (found in github.com/repo/projects/<ID>)
10+
*/
11+
assignIssue(issue: Issue): Promise<boolean>;
12+
// getProjectIdFromIssue(issueId: number): Promise<number>;
13+
// changeIssueStateInProject(issueId: number, state: "todo" | "in progress" | "blocked" | "done"): Promise<boolean>;
1414
}
1515

1616
/** Class managing the instance of issues */
1717
export interface IIssues {
18-
/**
19-
* Returns the state of an issue (open or closed)
20-
* @param issueId
21-
*/
22-
getIssueState(issueNumber: number): Promise<"open" | "closed">;
23-
/**
24-
* Returns the node_id for all the issues available in the repository
25-
* @param includeClosed exclude issues which are closed from the data agregation.
26-
*/
27-
getAllIssuesId(excludeClosed: boolean): Promise<Issue[]>;
18+
/**
19+
* Returns the state of an issue (open or closed)
20+
* @param issueId
21+
*/
22+
getIssueState(issueNumber: number): Promise<"open" | "closed">;
23+
/**
24+
* Returns the node_id for all the issues available in the repository
25+
* @param includeClosed exclude issues which are closed from the data agregation.
26+
*/
27+
getAllIssuesId(excludeClosed: boolean): Promise<Issue[]>;
2828
}
2929

3030
export interface ILogger {
31-
info(message: string): void;
32-
warning(message: string): void;
33-
error(message: string | Error): void;
34-
/** Only posts messages if the action is ran in debug mode */
35-
debug(message: string): void;
36-
/** Publishes a message that can be seen in the action preview */
37-
notice(message: string): void;
31+
info(message: string): void;
32+
warning(message: string): void;
33+
error(message: string | Error): void;
34+
/** Only posts messages if the action is ran in debug mode */
35+
debug(message: string): void;
36+
/** Publishes a message that can be seen in the action preview */
37+
notice(message: string): void;
3838
}

src/main.ts

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,43 @@
11
import { getInput, info, setFailed } from "@actions/core";
22
import { context, getOctokit } from "@actions/github";
3+
34
import { CoreLogger } from "./github/CoreLogger";
45
import { IssueApi } from "./github/issueKit";
56
import { ProjectKit } from "./github/projectKit";
67
import { GitHubContext, Synchronizer } from "./synchronizer";
78

8-
9-
//** Generates the class that will handle the project logic */
9+
//* * Generates the class that will handle the project logic */
1010
const generateSynchronizer = (): Synchronizer => {
11-
const repoToken = getInput("GITHUB_TOKEN", { required: true });
12-
const orgToken = getInput("PROJECT_TOKEN", { required: true });
11+
const repoToken = getInput("GITHUB_TOKEN", { required: true });
12+
const orgToken = getInput("PROJECT_TOKEN", { required: true });
1313

14-
const projectNumber = parseInt(getInput("project", { required: true }));
15-
// TODO: Add support for custom project fields (https://docs.github.com/en/issues/planning-and-tracking-with-projects/understanding-fields)
14+
const projectNumber = parseInt(getInput("project", { required: true }));
15+
// TODO: Add support for custom project fields (https://docs.github.com/en/issues/planning-and-tracking-with-projects/understanding-fields)
1616

17-
const { repo } = context;
17+
const { repo } = context;
1818

19-
const kit = getOctokit(repoToken);
20-
const issueKit = new IssueApi(kit, repo);
21-
const projectGraphQl = getOctokit(orgToken).graphql.defaults({ headers: { authorization: `token ${orgToken}` } });
22-
const logger = new CoreLogger();
23-
const projectKit = new ProjectKit(projectGraphQl, repo, projectNumber, logger);
19+
const kit = getOctokit(repoToken);
20+
const issueKit = new IssueApi(kit, repo);
21+
const projectGraphQl = getOctokit(orgToken).graphql.defaults({ headers: { authorization: `token ${orgToken}` } });
22+
const logger = new CoreLogger();
23+
const projectKit = new ProjectKit(projectGraphQl, repo, projectNumber, logger);
2424

25-
return new Synchronizer(issueKit, projectKit, logger);
26-
}
25+
return new Synchronizer(issueKit, projectKit, logger);
26+
};
2727

2828
const synchronizer = generateSynchronizer();
2929

3030
const { issue } = context.payload;
3131
const parsedContext: GitHubContext = {
32-
eventName: context.eventName,
33-
payload: {
34-
inputs: context.payload.inputs,
35-
issue: issue ? {
36-
number: issue.number,
37-
node_id: issue.node_id
38-
} : undefined
39-
}
40-
}
41-
42-
synchronizer.synchronizeIssue(parsedContext)
43-
.then(() => info("Finished"))
44-
.catch(setFailed);
32+
eventName: context.eventName,
33+
payload: {
34+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
35+
inputs: context.payload.inputs,
36+
issue: issue ? { number: issue.number, node_id: issue.node_id as string } : undefined,
37+
},
38+
};
39+
40+
synchronizer
41+
.synchronizeIssue(parsedContext)
42+
.then(() => info("Finished"))
43+
.catch(setFailed);

0 commit comments

Comments
 (0)