move package name validation to TS part of action
parent
7a6805e756
commit
a04ac8389d
|
@ -42,7 +42,7 @@ function run() {
|
|||
try {
|
||||
model_1.Action.checkCompatibility();
|
||||
const { dockerfile, workspace, actionFolder } = model_1.Action;
|
||||
const { unityVersion, customImage, projectPath, customParameters, testMode, artifactsPath, useHostNetwork, sshAgent, gitPrivateToken, githubToken, checkName, packageMode, } = model_1.Input.getFromUser();
|
||||
const { unityVersion, customImage, projectPath, customParameters, testMode, artifactsPath, useHostNetwork, sshAgent, gitPrivateToken, githubToken, checkName, packageMode, packageName, } = model_1.Input.getFromUser();
|
||||
const baseImage = new model_1.ImageTag({ version: unityVersion, customImage });
|
||||
try {
|
||||
// Build docker image
|
||||
|
@ -58,6 +58,7 @@ function run() {
|
|||
useHostNetwork,
|
||||
sshAgent,
|
||||
packageMode,
|
||||
packageName,
|
||||
gitPrivateToken,
|
||||
githubToken,
|
||||
});
|
||||
|
@ -169,7 +170,7 @@ const Docker = {
|
|||
},
|
||||
run(image, parameters, silent = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { unityVersion, workspace, projectPath, customParameters, testMode, artifactsPath, useHostNetwork, sshAgent, packageMode, gitPrivateToken, githubToken, } = parameters;
|
||||
const { unityVersion, workspace, projectPath, customParameters, testMode, artifactsPath, useHostNetwork, sshAgent, packageMode, packageName, gitPrivateToken, githubToken, } = parameters;
|
||||
const command = `docker run \
|
||||
--workdir /github/workspace \
|
||||
--rm \
|
||||
|
@ -184,6 +185,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 \
|
||||
|
@ -369,6 +371,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const unity_version_parser_1 = __importDefault(__nccwpck_require__(7049));
|
||||
const fs_1 = __importDefault(__nccwpck_require__(7147));
|
||||
const core_1 = __nccwpck_require__(2186);
|
||||
const Input = {
|
||||
get testModes() {
|
||||
|
@ -378,6 +381,33 @@ const Input = {
|
|||
const validFolderName = new RegExp(/^(\.|\.\/)?(\.?[\w~]+([ _-]?[\w~]+)*\/?)*$/);
|
||||
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_1.default.existsSync(packageJsonPath)) {
|
||||
throw new Error(`Invalid projectPath - Cannot find package.json at ${packageJsonPath}`);
|
||||
}
|
||||
let packageJson;
|
||||
try {
|
||||
packageJson = JSON.parse(fs_1.default.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 = (0, core_1.getInput)('unityVersion') || 'auto';
|
||||
|
@ -408,12 +438,16 @@ const Input = {
|
|||
if (rawPackageMode !== 'true' && rawPackageMode !== 'false') {
|
||||
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' ? unity_version_parser_1.default.read(projectPath) : rawUnityVersion;
|
||||
const packageMode = rawPackageMode === 'true';
|
||||
// Return sanitised input
|
||||
return {
|
||||
unityVersion,
|
||||
|
@ -428,6 +462,7 @@ const Input = {
|
|||
githubToken,
|
||||
checkName,
|
||||
packageMode,
|
||||
packageName,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -23,33 +23,20 @@ if [ "$PACKAGE_MODE" = "true" ]; then
|
|||
ls "$UNITY_PROJECT_PATH"
|
||||
echo ""
|
||||
|
||||
PACKAGE_JSON_PATH="$UNITY_PROJECT_PATH/package.json"
|
||||
if [ ! -f "$PACKAGE_JSON_PATH" ]; then
|
||||
echo "Unable to locate package.json from the given package path. Aborting..."
|
||||
exit 1
|
||||
fi
|
||||
echo "Creating an empty Unity project to add the package $PACKAGE_NAME to."
|
||||
|
||||
PACKAGE_NAME=$(cat "$PACKAGE_JSON_PATH" | jq -r ".name")
|
||||
|
||||
if [ -z $PACKAGE_NAME ]; then
|
||||
echo "Unable to parse package name from package.json. Aborting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Package name found: ${PACKAGE_NAME}"
|
||||
|
||||
echo "Creating an empty Unity project to add the package to."
|
||||
TEMP_PROJECT_PATH="./TempProject"
|
||||
|
||||
unity-editor \
|
||||
-batchmode \
|
||||
-createProject "./TempProject" \
|
||||
-createProject "$TEMP_PROJECT_PATH" \
|
||||
-quit
|
||||
|
||||
# use jq to add the package to the temp project through manually modifying Packages/manifest.json
|
||||
echo "Adding package to the temporary project's dependencies and testables..."
|
||||
echo ""
|
||||
|
||||
PACKAGE_MANIFEST_PATH="./TempProject/Packages/manifest.json"
|
||||
PACKAGE_MANIFEST_PATH="$TEMP_PROJECT_PATH/Packages/manifest.json"
|
||||
if [ ! -f "$PACKAGE_MANIFEST_PATH" ]; then
|
||||
echo "Packages/mainfest.json was not created properly. This indicates a problem with the Action, not with your package. Aborting..."
|
||||
exit 1
|
||||
|
@ -63,7 +50,7 @@ if [ "$PACKAGE_MODE" = "true" ]; then
|
|||
'.dependencies += {"\($packageName)": "file:\($projectPath)"} | . += {testables: ["\($packageName)"]}' \
|
||||
> "$PACKAGE_MANIFEST_PATH"
|
||||
|
||||
UNITY_PROJECT_PATH="./TempProject"
|
||||
UNITY_PROJECT_PATH="$TEMP_PROJECT_PATH"
|
||||
fi
|
||||
|
||||
#
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue