Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 9 additions & 5 deletions .github/actions/setup-node/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ description: Sets up Node.js environment

inputs:
version:
description: "The version of Node.js to use"
default: "24.x"
description: "The version of Node.js to use. When omitted, detect a compatible version."
default: ""
required: false
type: string

Expand All @@ -22,9 +22,13 @@ runs:
shell: bash
env:
npm_config_engine_strict: true
REQUESTED_NODE_VERSION: ${{ inputs.version }}
run: |
if [ -n "${REQUESTED_NODE_VERSION}" ]; then
Comment thread
Jamie-BitFlight marked this conversation as resolved.
NODE_VERSION="${REQUESTED_NODE_VERSION}"

# check if the installed node version works with the engines field in package.json
if npm ln --dry-run --ignore-scripts &>/dev/null; then
elif npm ln --dry-run --ignore-scripts &>/dev/null; then
NODE_VERSION="$(node -v)"

# check if .npmrc specifies a node version
Expand All @@ -43,8 +47,8 @@ runs:
fi

# check that we now have a node version, if not, use the default
if ! grep -qoP '^v?\d+\.(x|\d+\.)?(\d+|x)?' <<<"${NODE_VERSION}"; then
NODE_VERSION="${{ inputs.version || '24.x' }}"
if [ -z "${REQUESTED_NODE_VERSION}" ] && ! grep -qoP '^v?\d+\.(x|\d+\.)?(\d+|x)?' <<<"${NODE_VERSION}"; then
NODE_VERSION="24.x"
echo "::warning::Unable to determine Node.js version from project files, using default version ${NODE_VERSION}"
fi

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ jobs:
# step against the runner's actual npm version.
run-install: false

- name: Build action
- name: Build and verify packaged entry points
working-directory: action-under-test
run: npm run build
run: npm run test -- --run __tests__/integration-bundled-binary.test.ts

- name: Checkout target repository (${{ matrix.repo }})
uses: actions/checkout@v7.0.1
Expand Down
40 changes: 29 additions & 11 deletions __tests__/action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,27 @@ describe('Action', () => {
});
});

describe('nested metadata validation', () => {
describe('metadata validation', () => {
const metadata = {
name: 'Fixture action',
description: 'Fixture description',
runs: { using: 'node24', main: 'index.js' },
};

it.each(['node24', 42, true])('rejects scalar runs %j with metadata context', async (runs) => {
vi.mocked(fs.readFileSync).mockReturnValueOnce(YAML.stringify({ ...metadata, runs }));
const { default: Action } = await import('../src/Action.js');

expect(() => new Action(actTestYmlPath, mockLogTask)).toThrow(
expect.objectContaining({
message: expect.stringContaining(`Failed to load ${actTestYmlPath}`),
cause: expect.objectContaining({
message: `Invalid action metadata syntax in ${actTestYmlPath}.`,
}),
}),
);
});

it.each([
{ inputs: { option: null } },
{ inputs: { option: 42 } },
Expand All @@ -154,19 +168,23 @@ describe('Action', () => {
])('rejects malformed nested metadata through YAML loading: %j', async (nested) => {
vi.mocked(fs.readFileSync).mockReturnValueOnce(YAML.stringify({ ...metadata, ...nested }));
const { default: Action } = await import('../src/Action.js');
expect(() => new Action(actTestYmlPath, mockLogTask)).toThrow('Invalid action metadata syntax');
expect(() => new Action(actTestYmlPath, mockLogTask)).toThrow(
'Invalid action metadata syntax',
);
});

it('accepts scalar defaults and nullish descriptions through YAML loading', async () => {
vi.mocked(fs.readFileSync).mockReturnValueOnce(YAML.stringify({
...metadata,
inputs: {
enabled: { description: 'Enabled', default: false, required: false },
retries: { description: 'Retries', default: 3 },
optional: { default: null, description: null },
},
outputs: { result: { description: null } },
}));
vi.mocked(fs.readFileSync).mockReturnValueOnce(
YAML.stringify({
...metadata,
inputs: {
enabled: { description: 'Enabled', default: false, required: false },
retries: { description: 'Retries', default: 3 },
optional: { default: null, description: null },
},
outputs: { result: { description: null } },
}),
);
const { default: Action } = await import('../src/Action.js');
const action = new Action(actTestYmlPath, mockLogTask);
expect(action.inputs?.enabled?.default).toBe(false);
Expand Down
Loading
Loading