move package name validation to TS part of action

This commit is contained in:
Aaron Trudeau
2022-02-28 22:26:50 -05:00
parent 7a6805e756
commit a04ac8389d
7 changed files with 157 additions and 25 deletions

View File

@@ -19,6 +19,7 @@ async function run() {
githubToken,
checkName,
packageMode,
packageName,
} = Input.getFromUser();
const baseImage = new ImageTag({ version: unityVersion, customImage });
@@ -37,6 +38,7 @@ async function run() {
useHostNetwork,
sshAgent,
packageMode,
packageName,
gitPrivateToken,
githubToken,
});

View File

@@ -28,6 +28,7 @@ const Docker = {
useHostNetwork,
sshAgent,
packageMode,
packageName,
gitPrivateToken,
githubToken,
} = parameters;
@@ -46,6 +47,7 @@ const Docker = {
--env TEST_MODE="${testMode}" \
--env ARTIFACTS_PATH="${artifactsPath}" \
--env PACKAGE_MODE="${packageMode}" \
--env PACKAGE_NAME="${packageName}" \
--env GITHUB_REF \
--env GITHUB_SHA \
--env GITHUB_REPOSITORY \

View File

@@ -1,6 +1,9 @@
import Input from './input';
import fs from 'fs';
jest.mock('./unity-version-parser');
jest.mock('fs');
const mockedFs = fs as jest.Mocked<typeof fs>;
describe('Input', () => {
describe('getFromUser', () => {
@@ -33,4 +36,63 @@ describe('Input', () => {
expect(Input.isValidFolderName(folderName)).toStrictEqual(false);
});
});
describe('getPackageNameFromPackageJson', () => {
it('throws error if package.json cannot be found at the given project path', () => {
mockedFs.existsSync.mockReturnValue(false);
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
'Invalid projectPath - Cannot find package.json at some/path/package.json',
);
});
it('throws error if package.json contents cannot be parsed', () => {
mockedFs.existsSync.mockReturnValue(true);
mockedFs.readFileSync.mockReturnValue(Buffer.from('DefinitelyNotJSON'));
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
/Unable to parse package.json contents as JSON/,
);
});
it('throws error if name field in package.json is not present', () => {
mockedFs.existsSync.mockReturnValue(true);
mockedFs.readFileSync.mockReturnValue(
Buffer.from(JSON.stringify({ notName: 'some-package', alsoNotName: 'some-package' })),
);
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
'Unable to parse package name from package.json - package name should be string, but was undefined',
);
});
it('throws error if name field in package.json is present but not a string', () => {
mockedFs.existsSync.mockReturnValue(true);
mockedFs.readFileSync.mockReturnValue(
Buffer.from(JSON.stringify({ name: 3, notName: 'some-package' })),
);
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
'Unable to parse package name from package.json - package name should be string, but was number',
);
});
it('throws error if name field in package.json is present but empty', () => {
mockedFs.existsSync.mockReturnValue(true);
mockedFs.readFileSync.mockReturnValue(Buffer.from(JSON.stringify({ name: '', notName: 3 })));
expect(() => Input.getPackageNameFromPackageJson('some/path')).toThrow(
'Package name from package.json is a string, but is empty',
);
});
it('returns the name field in package.json if it is present as a non-empty string', () => {
mockedFs.existsSync.mockReturnValue(true);
mockedFs.readFileSync.mockReturnValue(
Buffer.from(JSON.stringify({ name: 'some-package', notName: 'not-what-we-want' })),
);
expect(Input.getPackageNameFromPackageJson('some/path')).toStrictEqual('some-package');
});
});
});

View File

@@ -1,4 +1,5 @@
import UnityVersionParser from './unity-version-parser';
import fs from 'fs';
import { getInput } from '@actions/core';
const Input = {
@@ -12,6 +13,42 @@ const Input = {
return validFolderName.test(folderName);
},
/**
* When in package mode, we need scrape the package's name from its package.json file
*/
getPackageNameFromPackageJson(packagePath) {
const packageJsonPath = `${packagePath}/package.json`;
if (!fs.existsSync(packageJsonPath)) {
throw new Error(`Invalid projectPath - Cannot find package.json at ${packageJsonPath}`);
}
let packageJson;
try {
packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString());
} catch (error) {
if (error instanceof SyntaxError) {
throw new SyntaxError(`Unable to parse package.json contents as JSON - ${error.message}`);
}
throw new Error(`Unable to parse package.json contents as JSON - unknown error ocurred`);
}
const rawPackageName = packageJson.name;
if (typeof rawPackageName !== 'string') {
throw new TypeError(
`Unable to parse package name from package.json - package name should be string, but was ${typeof rawPackageName}`,
);
}
if (rawPackageName.length === 0) {
throw new Error(`Package name from package.json is a string, but is empty`);
}
return rawPackageName;
},
getFromUser() {
// Input variables specified in workflow using "with" prop.
const rawUnityVersion = getInput('unityVersion') || 'auto';
@@ -48,13 +85,19 @@ const Input = {
throw new Error(`Invalid packageMode "${rawPackageMode}"`);
}
// Sanitise input
// sanitize packageMode input and projectPath input since they are needed
// for input validation
const packageMode = rawPackageMode === 'true';
const projectPath = rawProjectPath.replace(/\/$/, '');
// if in package mode, attempt to get the package's name
const packageName = packageMode ? this.getPackageNameFromPackageJson(projectPath) : '';
// Sanitise other input
const artifactsPath = rawArtifactsPath.replace(/\/$/, '');
const useHostNetwork = rawUseHostNetwork === 'true';
const unityVersion =
rawUnityVersion === 'auto' ? UnityVersionParser.read(projectPath) : rawUnityVersion;
const packageMode = rawPackageMode === 'true';
// Return sanitised input
return {
@@ -70,6 +113,7 @@ const Input = {
githubToken,
checkName,
packageMode,
packageName,
};
},
};