Skip to content

Commit c754314

Browse files
authored
convert action source and tests to TypeScript (#100)
1 parent f6d25d6 commit c754314

File tree

14 files changed

+381
-217
lines changed

14 files changed

+381
-217
lines changed

.oxlintrc.json

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "./node_modules/oxlint/configuration_schema.json",
3-
"plugins": ["import", "promise", "unicorn"],
3+
"plugins": ["import", "promise", "typescript", "unicorn"],
44
"ignorePatterns": ["**/dist"],
55
"rules": {
66
"curly": "error",
@@ -36,6 +36,32 @@
3636
"import/no-self-import": "error",
3737
"promise/always-return": "error",
3838
"promise/no-callback-in-promise": "error",
39+
"typescript/await-thenable": "error",
40+
"typescript/ban-ts-comment": [
41+
"error",
42+
{
43+
"minimumDescriptionLength": 3,
44+
"ts-check": false,
45+
"ts-expect-error": "allow-with-description",
46+
"ts-ignore": true,
47+
"ts-nocheck": true
48+
}
49+
],
50+
"typescript/consistent-type-imports": ["error", { "fixStyle": "inline-type-imports" }],
51+
"typescript/no-confusing-non-null-assertion": "error",
52+
"typescript/no-extra-non-null-assertion": "error",
53+
"typescript/no-misused-promises": ["error", { "checksVoidReturn": false }],
54+
"typescript/no-restricted-types": "error",
55+
"typescript/no-unnecessary-boolean-literal-compare": "error",
56+
"typescript/no-unnecessary-type-arguments": "error",
57+
"typescript/no-unnecessary-type-assertion": "error",
58+
"typescript/no-unnecessary-type-constraint": "error",
59+
"typescript/no-unsafe-enum-comparison": "error",
60+
"typescript/prefer-includes": "error",
61+
"typescript/prefer-nullish-coalescing": "error",
62+
"typescript/prefer-readonly": "error",
63+
"typescript/return-await": ["error", "error-handling-correctness-only"],
64+
"typescript/unbound-method": "off",
3965
"unicorn/consistent-date-clone": "error",
4066
"unicorn/consistent-empty-array-spread": "error",
4167
"unicorn/consistent-existence-index-check": "error",

dist/index.js

Lines changed: 30 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
"author": "Simek <me@simek.dev>",
77
"license": "MIT",
88
"scripts": {
9-
"build": "esbuild src/action.js --bundle --platform=node --target=node22 --minify --legal-comments=none --outfile=dist/index.js",
10-
"lint": "oxlint && oxfmt --check",
11-
"lint:fix": "oxlint --fix && oxfmt",
9+
"build": "esbuild src/action.ts --bundle --platform=node --target=node22 --minify --legal-comments=none --outfile=dist/index.js",
10+
"lint": "oxlint --type-aware && oxfmt --check",
11+
"lint:fix": "oxlint --type-aware --fix && oxfmt",
1212
"optimize": "svgo -f ./assets",
13-
"test": "uvu tests -i .cjs -i testUtils"
13+
"test": "node --import tsx --test"
1414
},
1515
"dependencies": {
1616
"@actions/core": "^3.0.0",
@@ -20,12 +20,16 @@
2020
"semver": "^7.7.3"
2121
},
2222
"devDependencies": {
23+
"@types/node": "24.1.0",
24+
"@types/semver": "^7.7.1",
2325
"@yarnpkg/lockfile": "^1.1.0",
2426
"@yarnpkg/parsers": "^3.0.3",
2527
"esbuild": "^0.27.2",
2628
"oxfmt": "^0.27.0",
2729
"oxlint": "^1.42.0",
28-
"uvu": "^0.5.6"
30+
"oxlint-tsgolint": "^0.11.4",
31+
"tsx": "^4.21.0",
32+
"typescript": "^5.9.3"
2933
},
3034
"volta": {
3135
"node": "24.13.0",

src/action.js renamed to src/action.ts

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import { debug, getBooleanInput, getInput, setFailed, warning } from '@actions/core';
22
import { context, getOctokit } from '@actions/github';
3+
import { type operations } from '@octokit/openapi-types';
4+
import { type Api } from '@octokit/plugin-rest-endpoint-methods';
35
import { Base64 } from 'js-base64';
46
import { existsSync, readFileSync } from 'node:fs';
57
import { resolve } from 'node:path';
68

7-
import { createSummary, createTable } from './comment.mjs';
8-
import { countStatuses, diffLocks, parseLock, STATUS } from './utils.mjs';
9+
import { createSummary, createTable } from './comment';
10+
import { countStatuses, diffLocks, parseLock, STATUS } from './utils';
911

10-
async function getCommentId(octokit, oktokitParams, issueNumber, commentHeader) {
12+
async function getCommentId(
13+
octokit: Api,
14+
oktokitParams: { owner: string; repo: string },
15+
issueNumber: number,
16+
commentHeader: string
17+
) {
1118
const currentComments = await octokit.rest.issues.listComments({
1219
...oktokitParams,
1320
issue_number: issueNumber,
@@ -19,11 +26,11 @@ async function getCommentId(octokit, oktokitParams, issueNumber, commentHeader)
1926
}
2027

2128
return currentComments.data
22-
.filter(({ user, body }) => user.login === 'github-actions[bot]' && body.startsWith(commentHeader))
29+
.filter(({ user, body }) => user?.login === 'github-actions[bot]' && body?.startsWith(commentHeader))
2330
.map(({ id }) => id)[0];
2431
}
2532

26-
function getBasePathFromInput(input) {
33+
function getBasePathFromInput(input: string) {
2734
return input.lastIndexOf('/') ? input.substring(0, input.lastIndexOf('/')) : '';
2835
}
2936

@@ -38,14 +45,20 @@ async function run() {
3845

3946
const { owner, repo, number } = context.issue;
4047

41-
if (!number) {
48+
if (!number || !context.payload.pull_request) {
4249
throw Error('💥 Cannot find the PR data in the workflow context, aborting!');
4350
}
4451

4552
const { ref } = context.payload.pull_request.base;
46-
const { default_branch } = context.payload.repository;
53+
const contextRepo = context.payload?.repository;
4754

48-
const baseBranch = ref || default_branch;
55+
if (!contextRepo) {
56+
throw Error('💥 Cannot find the repository data in the workflow context, aborting!');
57+
}
58+
59+
const { default_branch } = contextRepo;
60+
61+
const baseBranch = ref ?? default_branch;
4962
debug('Base branch: ' + baseBranch);
5063

5164
const lockPath = resolve(process.cwd(), inputPath);
@@ -56,6 +69,9 @@ async function run() {
5669

5770
const content = readFileSync(lockPath, { encoding: 'utf8' });
5871
const updatedLock = parseLock(content);
72+
if (updatedLock.type === 'error') {
73+
warning('Unsupported Yarn lock version! Please report this issue in the action repository.');
74+
}
5975

6076
const oktokitParams = { owner, repo };
6177
debug('Oktokit params: ' + JSON.stringify(oktokitParams));
@@ -73,7 +89,10 @@ async function run() {
7389
throw Error('💥 Cannot fetch repository base branch tree, aborting!');
7490
}
7591

76-
const baseLockSHA = baseTree.data.tree.filter(file => file.path === 'yarn.lock')[0].sha;
92+
const baseLockSHA = baseTree.data.tree.filter(
93+
(file: operations['repos/get-content']['responses']['200']['content']['application/vnd.github.object']) =>
94+
file.path === 'yarn.lock'
95+
)[0].sha;
7796

7897
debug('Base lockfile SHA: ' + baseLockSHA);
7998

@@ -155,7 +174,11 @@ async function run() {
155174
}
156175
}
157176
} catch (error) {
158-
setFailed(error.message);
177+
if (error instanceof Error) {
178+
setFailed(error.message);
179+
} else if (typeof error === 'string') {
180+
setFailed(error);
181+
}
159182
}
160183
}
161184

src/comment.mjs renamed to src/comment.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { markdownTable } from 'markdown-table';
22

3-
import { countStatuses, STATUS_ORDER } from './utils.mjs';
3+
import { type LockChanges, type StausType } from './types';
4+
import { countStatuses, STATUS_ORDER } from './utils';
45

56
const ASSETS_URL = {
67
ADDED: 'https://git.io/J38HP',
@@ -16,11 +17,11 @@ const ASSETS_WIDTH = {
1617
UPDATED: 60,
1718
};
1819

19-
function getStatusLabel(status) {
20+
function getStatusLabel(status: StausType) {
2021
return `[<sub><img alt="${status}" src="${ASSETS_URL[status]}" height="16" width="${ASSETS_WIDTH[status]}" /></sub>](#)`;
2122
}
2223

23-
export function createTable(lockChanges, groupByType = false, plainStatuses = false) {
24+
export function createTable(lockChanges: Record<string, LockChanges>, groupByType = false, plainStatuses = false) {
2425
return markdownTable(
2526
[
2627
['Name', 'Status', 'Previous', 'Current'],
@@ -41,14 +42,14 @@ export function createTable(lockChanges, groupByType = false, plainStatuses = fa
4142
);
4243
}
4344

44-
function createSummaryRow(lockChanges, status) {
45+
function createSummaryRow(lockChanges: Record<string, LockChanges>, status: keyof typeof ASSETS_URL) {
4546
const statusCount = countStatuses(lockChanges, status);
46-
return statusCount ? [getStatusLabel(status), statusCount] : undefined;
47+
return statusCount ? [getStatusLabel(status), statusCount.toString()] : [undefined];
4748
}
4849

49-
export function createSummary(lockChanges) {
50-
return markdownTable(
51-
[['Status', 'Count'], ...STATUS_ORDER.map(status => createSummaryRow(lockChanges, status))].filter(Boolean),
52-
{ align: ['l', 'c'], alignDelimiters: false }
53-
);
50+
export function createSummary(lockChanges: Record<string, LockChanges>) {
51+
return markdownTable([['Status', 'Count'], ...STATUS_ORDER.map(status => createSummaryRow(lockChanges, status))], {
52+
align: ['l', 'c'],
53+
alignDelimiters: false,
54+
});
5455
}

src/types.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export type StausType = 'ADDED' | 'DOWNGRADED' | 'REMOVED' | 'UPDATED';
2+
3+
export type ParsedLock = {
4+
type: 'error' | 'success';
5+
object: Record<string, ClassicYarnEntry | BerryYarnEntry>;
6+
};
7+
8+
export type LockChanges = {
9+
previous: string;
10+
current: string;
11+
status: StausType;
12+
};
13+
14+
export type ClassicYarnEntry = {
15+
version: string;
16+
resolved: string;
17+
integrity: string;
18+
dependencies: Record<string, string>;
19+
};
20+
21+
export type BerryYarnEntry = {
22+
version: string;
23+
resolved: string;
24+
integrity: string;
25+
language: string;
26+
link: string;
27+
dependencies: Record<string, string>;
28+
peerDependencies: Record<string, string>;
29+
};

0 commit comments

Comments
 (0)