Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
974d216
Add clean command
leeyi45 Apr 6, 2026
41979c6
Update bundles to work with Typescript 6
leeyi45 Apr 6, 2026
c6e6024
Update tabs to work with typescript 6
leeyi45 Apr 6, 2026
372a933
Update github actions to work with Typescript 6
leeyi45 Apr 6, 2026
1b88ee4
Update libs to work with Typescript 6
leeyi45 Apr 6, 2026
467d090
Update ESLint packages
leeyi45 Apr 6, 2026
77150eb
Needed to revert back to ESLint 9
leeyi45 Apr 6, 2026
3a2ac5a
Update typedoc
leeyi45 Apr 6, 2026
8f6a3d3
Fix dependencies for lintplugin
leeyi45 Apr 6, 2026
e938d2b
Fix broken test
leeyi45 Apr 7, 2026
fbdee21
Test a potential broken action
leeyi45 Apr 7, 2026
6ba6b6c
Try another fix
leeyi45 Apr 7, 2026
3c1ad58
More testing
leeyi45 Apr 7, 2026
99e6f1e
Try adding silent to exec option
leeyi45 Apr 7, 2026
268c945
Augment code to see where execution stopped
leeyi45 Apr 7, 2026
19c176d
Try with more logging
leeyi45 Apr 7, 2026
4c3cf5b
Redo the implementation for getRawPackages to use yarn workspaces list
leeyi45 Apr 7, 2026
0c44216
Fix broken tests
leeyi45 Apr 7, 2026
280f242
Investigate using a try block
leeyi45 Apr 7, 2026
9aa9dd6
Try without memoization
leeyi45 Apr 7, 2026
55fe824
Try testing the yarn why command without silent
leeyi45 Apr 7, 2026
1849e5a
Fix package name extractor
leeyi45 Apr 7, 2026
2a1d7b9
Make package type information available too
leeyi45 Apr 7, 2026
948a6dd
Fix incorrect lib typing in tests
leeyi45 Apr 7, 2026
fea050e
Fix sound test using global
leeyi45 Apr 7, 2026
c105e43
Fix CurveAnimations crashing the frontend
leeyi45 Apr 7, 2026
962e428
Fix types and documentation
leeyi45 Apr 7, 2026
fc4fde8
Add result handling for the clean command
leeyi45 Apr 7, 2026
30447a8
Added documentation about the instanceof issue
leeyi45 Apr 7, 2026
d56aed5
Add Typescript to docs
leeyi45 Apr 7, 2026
5161209
Fix linting config to always require json extension
leeyi45 Apr 7, 2026
d9aec50
Fix toSpawn checks for tabs that weren't working
leeyi45 Apr 8, 2026
ab9ff8a
Fix broken tests
leeyi45 Apr 8, 2026
de6f6ae
Update tab test snapshots
leeyi45 Apr 9, 2026
c37d245
Update the docs about the ModuleTab type
leeyi45 Apr 9, 2026
ab21f78
Fix missing export and incorrect css layout
leeyi45 Apr 9, 2026
b0d6ed3
Fix WASM bundle
RichDom2185 Apr 10, 2026
e867f59
Merge branch 'ts-6' of github.com:source-academy/modules into ts-6
leeyi45 Apr 11, 2026
ae85b05
Update configurations
leeyi45 Apr 11, 2026
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
4 changes: 2 additions & 2 deletions .github/actions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
"devDependencies": {
"@sourceacademy/modules-repotools": "workspace:^",
"@types/node": "^22.15.30",
"typescript": "^5.8.2",
"typescript": "^6.0.2",
"vitest": "4.1.0"
},
"dependencies": {
"@actions/artifact": "^6.0.0",
"@actions/core": "^1.11.1",
"@actions/core": "^3.0.0",
"@actions/exec": "^3.0.0",
"es-toolkit": "^1.44.0",
"snyk-nodejs-lockfile-parser": "^2.4.2"
Expand Down
5 changes: 5 additions & 0 deletions .github/actions/src/__tests__/lockfiles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ describe(utils.extractPackageName, () => {
.toEqual('lodash');
});

it('works on this weird patch thing', () => {
expect(utils.extractPackageName('typescript@patch:typescript@npm:6.0.2'))
.toEqual('typescript');
});

it('throws an error on an invalid package name', () => {
expect(() => utils.extractPackageName('something weird'))
.toThrowError('Invalid package name: something weird');
Expand Down
26 changes: 22 additions & 4 deletions .github/actions/src/commons.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { getExecOutput } from '@actions/exec';
import { memoize } from 'es-toolkit';

type PackageType = 'bundle' | 'tab' | 'lib' | null;

export interface RawPackageRecord {
directory: string;
hasChanges: boolean;
Expand All @@ -9,9 +11,10 @@ export interface RawPackageRecord {
devDependencies: Record<string, string>;
dependencies: Record<string, string>;
};
type: PackageType;
}

interface BasePackageRecord {
interface BasePackageRecord<T extends PackageType> {
/**
* Directory within which the `package.json` file was found
*/
Expand All @@ -31,17 +34,19 @@ interface BasePackageRecord {
* might need playwright for its tests
*/
needsPlaywright: boolean;

type: T;
}

export interface BundlePackageRecord extends BasePackageRecord {
export interface BundlePackageRecord extends BasePackageRecord<'bundle'> {
bundleName: string;
}

export interface TabPackageRecord extends BasePackageRecord {
export interface TabPackageRecord extends BasePackageRecord<'tab'> {
tabName: string;
}

export type PackageRecord = BundlePackageRecord | TabPackageRecord | BasePackageRecord;
export type PackageRecord = BundlePackageRecord | TabPackageRecord | BasePackageRecord<'lib' | null>;

export function isPackageRecord(obj: unknown): obj is PackageRecord {
if (typeof obj !== 'object' || obj === null) return false;
Expand Down Expand Up @@ -76,3 +81,16 @@ export const checkDirForChanges = memoize(async (directory: string) => {
);
return exitCode !== 0;
});

/**
* Format of each entry produced when running the command `yarn workspaces list --json`.
*/
export interface YarnWorkspaceRecord {
location: string;
name: string;
}

export async function runYarnWorkspacesList() {
const { stdout } = await getExecOutput('yarn workspaces list --json', [], { silent: true });
return stdout.trim();
}
57 changes: 23 additions & 34 deletions .github/actions/src/info/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import fs from 'fs/promises';
import pathlib from 'path';
import * as core from '@actions/core';
import { describe, expect, test, vi } from 'vitest';
import * as git from '../../commons.js';
import * as commons from '../../commons.js';
import * as lockfiles from '../../lockfiles.js';
import { getAllPackages, getRawPackages, main } from '../index.js';

const mockedCheckChanges = vi.spyOn(git, 'checkDirForChanges');
const mockedCheckChanges = vi.spyOn(commons, 'checkDirForChanges');

vi.mock(import('path'), async importOriginal => {
const { posix } = await importOriginal();
Expand All @@ -22,6 +22,14 @@ vi.mock(import('../../gitRoot.js'), () => ({
gitRoot: 'root'
}));

vi.mock(import('@actions/core'), async importOriginal => {
const original = await importOriginal();
return {
...original,
setOutput: vi.fn((_name, _value) => {})
};
});

class NodeError extends Error {
constructor(public readonly code: string) {
super();
Expand Down Expand Up @@ -119,42 +127,23 @@ function mockReadFile(path: string) {
return recurser(segments, { root: mockDirectory });
}

function getMockYarnWorkspaceRecords(): commons.YarnWorkspaceRecord[] {
return [
{ location: '.', name: '@sourceacademy/modules' },
{ location: 'lib/modules-lib', name: '@sourceacademy/modules-lib' },
{ location: 'src/bundles/bundle0', name: '@sourceacademy/bundle-bundle0' },
{ location: 'src/tabs/tab0', name: '@sourceacademy/tab-Tab0' },
];
}

vi.spyOn(fs, 'readdir').mockImplementation(mockReaddir as any);
vi.spyOn(fs, 'readFile').mockImplementation(mockReadFile as any);
vi.spyOn(lockfiles, 'hasLockFileChanged').mockResolvedValue(false);
vi.spyOn(commons, 'runYarnWorkspacesList').mockResolvedValue(
getMockYarnWorkspaceRecords().map(each => JSON.stringify(each)).join('\n')
);

describe(getRawPackages, () => {
test('maxDepth = 1', async () => {
mockedCheckChanges.mockResolvedValueOnce(true);
const results = Object.entries(await getRawPackages('root', 1));
expect(fs.readdir).toHaveBeenCalledTimes(3);
expect(results.length).toEqual(1);

const [[name, packageData]] = results;
expect(name).toEqual('@sourceacademy/modules');
expect(packageData.hasChanges).toEqual(true);
expect(git.checkDirForChanges).toHaveBeenCalledOnce();
});

test('maxDepth = 3', async () => {
mockedCheckChanges.mockResolvedValue(true);
const results = await getRawPackages('root', 3);
expect(Object.values(results).length).toEqual(4);
expect(fs.readdir).toHaveBeenCalledTimes(8);

expect(results).toHaveProperty('@sourceacademy/bundle-bundle0');
const bundleResult = results['@sourceacademy/bundle-bundle0'];
expect(bundleResult.hasChanges).toEqual(true);

expect(results).toHaveProperty('@sourceacademy/tab-Tab0');
const tabResult = results['@sourceacademy/tab-Tab0'];
expect(tabResult.hasChanges).toEqual(true);

expect(results).toHaveProperty('@sourceacademy/modules-lib');
const libResult = results['@sourceacademy/modules-lib'];
expect(libResult.hasChanges).toEqual(true);
});

test('hasChanges fields accurately reflects value returned from checkChanges', async () => {
mockedCheckChanges.mockImplementation(p => {
switch (p) {
Expand Down Expand Up @@ -221,7 +210,7 @@ describe(getAllPackages, () => {
});

describe(main, () => {
const mockedSetOutput = vi.spyOn(core, 'setOutput');
const mockedSetOutput = vi.mocked(core.setOutput);

vi.spyOn(core.summary, 'addHeading').mockImplementation(() => core.summary);
vi.spyOn(core.summary, 'addTable').mockImplementation(() => core.summary);
Expand Down
6 changes: 6 additions & 0 deletions .github/actions/src/info/__tests__/sorter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ describe(topoSortPackages, () => {
test('Without a cycle', () => {
const result = topoSortPackages({
'@sourceacademy/0': {
type: null,
hasChanges: false,
directory: '/',
package: {
Expand All @@ -16,6 +17,7 @@ describe(topoSortPackages, () => {
}
},
'@sourceacademy/1': {
type: null,
hasChanges: false,
directory: '/',
package: {
Expand All @@ -27,6 +29,7 @@ describe(topoSortPackages, () => {
}
},
'@sourceacademy/2': {
type: null,
hasChanges: false,
directory: '/',
package: {
Expand All @@ -47,6 +50,7 @@ describe(topoSortPackages, () => {
test('With a cycle', () => {
const func = () => topoSortPackages({
'@sourceacademy/0': {
type: null,
hasChanges: false,
directory: '/',
package: {
Expand All @@ -58,6 +62,7 @@ describe(topoSortPackages, () => {
}
},
'@sourceacademy/1': {
type: null,
hasChanges: false,
directory: '/',
package: {
Expand All @@ -69,6 +74,7 @@ describe(topoSortPackages, () => {
}
},
'@sourceacademy/2': {
type: null,
hasChanges: false,
directory: '/',
package: {
Expand Down
Loading
Loading