This commit updates the @actions/core dependency from v2 to v3. The primary change in @actions/core v3 is that it is now an ESM-only package. To maintain compatibility, the following changes were made: - Added "type": "module" to package.json to switch the project to ESM. - Converted index.js from CommonJS to ESM, replacing require with import/export. - Converted __tests__/index.test.js to ESM to support testing the updated index.js. - Re-built the production bundle in dist/ using ncc to reflect the changes. - Updated the main entry point check in index.js to use import.meta.url for ESM compatibility. This ensures the action continues to function correctly with the latest GitHub Actions toolkit library.
200 lines
6.5 KiB
JavaScript
200 lines
6.5 KiB
JavaScript
import {
|
|
validateAuthentication,
|
|
replacePlaceholders,
|
|
readReplaceAndWriteFiles,
|
|
readFilesIntoDict,
|
|
} from "../index.js";
|
|
import fs from "fs";
|
|
import path from "path";
|
|
import os from "os";
|
|
import { glob } from "glob";
|
|
|
|
describe("validateAuthentication", () => {
|
|
it("should return null when only token is provided", () => {
|
|
expect(validateAuthentication("token", null, null)).toBeNull();
|
|
});
|
|
|
|
it("should return an error message when token and username are provided", () => {
|
|
expect(validateAuthentication("token", "user", null)).toBe(
|
|
"Token is defined along with username and/or password.",
|
|
);
|
|
});
|
|
|
|
it("should return an error message when token and password are provided", () => {
|
|
expect(validateAuthentication("token", null, "pass")).toBe(
|
|
"Token is defined along with username and/or password.",
|
|
);
|
|
});
|
|
|
|
it("should return an error message when token, username, and password are provided", () => {
|
|
expect(validateAuthentication("token", "user", "pass")).toBe(
|
|
"Token is defined along with username and/or password.",
|
|
);
|
|
});
|
|
|
|
it("should return an error message when no credentials are provided", () => {
|
|
expect(validateAuthentication(null, null, null)).toBe(
|
|
"Neither token nor password and username are defined.",
|
|
);
|
|
});
|
|
|
|
it("should return an error message when only username is provided", () => {
|
|
expect(validateAuthentication(null, "user", null)).toBe(
|
|
"Username is defined but no password is provided.",
|
|
);
|
|
});
|
|
|
|
it("should return an error message when only password is provided", () => {
|
|
expect(validateAuthentication(null, null, "pass")).toBe(
|
|
"Password is defined but no username is provided.",
|
|
);
|
|
});
|
|
|
|
it("should return null when username and password are provided", () => {
|
|
expect(validateAuthentication(null, "user", "pass")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("replacePlaceholders", () => {
|
|
beforeEach(() => {
|
|
process.env.GITHUB_SHA = "test-sha";
|
|
process.env.GITHUB_REF = "test-ref";
|
|
});
|
|
|
|
it("should replace all placeholders", () => {
|
|
const content =
|
|
"hash: {{gitHash}}, ref: {{gitRef}}, time: {{deployTime}}, host: {{hostname}}";
|
|
const replacedContent = replacePlaceholders(content, "test-host");
|
|
expect(replacedContent).toMatch(/hash: test-sha/);
|
|
expect(replacedContent).toMatch(/ref: test-ref/);
|
|
expect(replacedContent).toMatch(/time: .*/);
|
|
expect(replacedContent).toMatch(/host: test-host/);
|
|
});
|
|
});
|
|
|
|
describe("readReplaceAndWriteFiles", () => {
|
|
let tempDir;
|
|
|
|
beforeEach(async () => {
|
|
tempDir = await fs.promises.mkdtemp(
|
|
path.join(os.tmpdir(), "replace-test-"),
|
|
);
|
|
process.env.GITHUB_SHA = "test-sha";
|
|
process.env.GITHUB_REF = "test-ref";
|
|
});
|
|
|
|
afterEach(async () => {
|
|
if (tempDir) {
|
|
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("should find files and replace placeholders", async () => {
|
|
const fileName = "test.js";
|
|
const filePath = path.join(tempDir, fileName);
|
|
const content = "hash: {{gitHash}}, ref: {{gitRef}}, host: {{hostname}}";
|
|
await fs.promises.writeFile(filePath, content);
|
|
|
|
const pattern = "*.js";
|
|
// We pass tempDir as the prefix so glob searches inside it
|
|
await readReplaceAndWriteFiles(pattern, tempDir, "test-host");
|
|
|
|
const updatedContent = await fs.promises.readFile(filePath, "utf8");
|
|
|
|
expect(updatedContent).toContain("hash: test-sha");
|
|
expect(updatedContent).toContain("ref: test-ref");
|
|
expect(updatedContent).toContain("host: test-host");
|
|
});
|
|
});
|
|
|
|
describe("readFilesIntoDict", () => {
|
|
let tempDir;
|
|
|
|
beforeEach(async () => {
|
|
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "read-test-"));
|
|
await fs.promises.mkdir(path.join(tempDir, "subdir"), { recursive: true });
|
|
});
|
|
|
|
afterEach(async () => {
|
|
if (tempDir) {
|
|
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("should read files into a dictionary with correct keys", async () => {
|
|
const file1 = "file1.js";
|
|
const content1 = "content1";
|
|
await fs.promises.writeFile(path.join(tempDir, file1), content1);
|
|
|
|
const file2 = "subdir/file2.js";
|
|
const content2 = "content2";
|
|
await fs.promises.writeFile(path.join(tempDir, file2), content2);
|
|
|
|
const pattern = "**/*.js";
|
|
const result = await readFilesIntoDict(pattern, tempDir);
|
|
|
|
// Keys should be relative paths without extension
|
|
// On Windows, the path separator might differ, so we should be careful or just check contents
|
|
|
|
// Based on implementation:
|
|
// key = key.slice(prefix.length);
|
|
// key = path.basename(key, path.extname(key)); // Drop the file suffix -> THIS IS BUGGY for subdirs?
|
|
|
|
// Let's check the implementation of readFilesIntoDict again in index.js
|
|
// It does: key = path.basename(key, path.extname(key));
|
|
// This removes the directory part! So subdir/file2.js becomes file2
|
|
|
|
expect(result["file1"]).toBe(content1);
|
|
expect(result["file2"]).toBe(content2);
|
|
});
|
|
});
|
|
|
|
describe("glob functionality", () => {
|
|
let tempDir;
|
|
|
|
beforeEach(async () => {
|
|
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "glob-test-"));
|
|
await fs.promises.mkdir(path.join(tempDir, "lib"), { recursive: true });
|
|
await fs.promises.mkdir(path.join(tempDir, "deep", "folder"), {
|
|
recursive: true,
|
|
});
|
|
await fs.promises.writeFile(path.join(tempDir, "main.js"), "content");
|
|
await fs.promises.writeFile(path.join(tempDir, "utils.js"), "content");
|
|
await fs.promises.writeFile(
|
|
path.join(tempDir, "lib", "helper.js"),
|
|
"content",
|
|
);
|
|
await fs.promises.writeFile(
|
|
path.join(tempDir, "lib", "data.json"),
|
|
"content",
|
|
);
|
|
await fs.promises.writeFile(
|
|
path.join(tempDir, "deep", "folder", "main.js"),
|
|
"content",
|
|
);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
if (tempDir) {
|
|
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("should find all javascript files in the directory", async () => {
|
|
// Ensure pattern uses forward slashes for glob
|
|
const pattern = path.join(tempDir, "**", "*.js").split(path.sep).join("/");
|
|
const files = await glob(pattern);
|
|
|
|
// Normalize file paths to system separator (backslashes on Windows)
|
|
const normalizedFiles = files.map((f) => path.normalize(f));
|
|
|
|
const expectedFiles = [
|
|
path.join(tempDir, "deep", "folder", "main.js"),
|
|
path.join(tempDir, "lib", "helper.js"),
|
|
path.join(tempDir, "main.js"),
|
|
path.join(tempDir, "utils.js"),
|
|
].sort();
|
|
expect(normalizedFiles.sort()).toEqual(expectedFiles);
|
|
});
|
|
});
|