Skip to content
Draft
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
7 changes: 7 additions & 0 deletions .changeset/smooth-socks-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@nomicfoundation/hardhat-errors": patch
"@nomicfoundation/hardhat-verify": patch
"hardhat": patch
---

Added support for `inline actions` in tasks [7851](https://github.com/NomicFoundation/hardhat/pull/7851).
16 changes: 16 additions & 0 deletions v-next/hardhat-errors/src/descriptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,22 @@ Please double check your arguments.`,

Please check you have the correct subtask.`,
},
INLINE_ACTION_CANNOT_BE_USED_IN_PLUGINS: {
number: 417,
messageTemplate: `The task "{task}" defines an "inlineAction", which is not allowed in plugins.`,
websiteTitle: "Inline action not allowed in plugins",
websiteDescription: `Plugins are not allowed to use inline actions for tasks.

Please define the action in a separate file and reference it.`,
},
ACTION_ALREADY_SET: {
number: 418,
messageTemplate: `The action for task "{task}" has already been set. You can only call "setAction" or "setInlineAction" once per task definition.`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self reminder: If we change to "lazy actions", this must be updated

websiteTitle: "Task action already set",
websiteDescription: `A task definition can only have one action. You cannot call "setAction" or "setInlineAction" more than once on the same task builder.

Please remove the duplicate call.`,
},
},
ARGUMENTS: {
INVALID_VALUE_FOR_TYPE: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { NewTaskDefinition } from "hardhat/types/tasks";
import type { PluginTaskDefinition } from "hardhat/types/plugins";

import { task } from "hardhat/config";

import { extendWithVerificationArgs } from "../utils.js";

const verifyBlockscoutTask: NewTaskDefinition = extendWithVerificationArgs(
const verifyBlockscoutTask: PluginTaskDefinition = extendWithVerificationArgs(
task(["verify", "blockscout"], "Verify a contract on Blockscout"),
)
.setAction(() => import("./task-action.js"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { NewTaskDefinition } from "hardhat/types/tasks";
import type { PluginTaskDefinition } from "hardhat/types/plugins";

import { task } from "hardhat/config";

import { extendWithVerificationArgs } from "../utils.js";

const verifyEtherscanTask: NewTaskDefinition = extendWithVerificationArgs(
const verifyEtherscanTask: PluginTaskDefinition = extendWithVerificationArgs(
task(["verify", "etherscan"], "Verify a contract on Etherscan"),
)
.setAction(() => import("./task-action.js"))
Expand Down
4 changes: 2 additions & 2 deletions v-next/hardhat-verify/src/internal/tasks/verify/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { NewTaskDefinition } from "hardhat/types/tasks";
import type { PluginTaskDefinition } from "hardhat/types/plugins";

import { task } from "hardhat/config";

import { extendWithSourcifyArgs, extendWithVerificationArgs } from "./utils.js";

const verifyTask: NewTaskDefinition = extendWithSourcifyArgs(
const verifyTask: PluginTaskDefinition = extendWithSourcifyArgs(
extendWithVerificationArgs(
task("verify", "Verify a contract on all supported explorers"),
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { NewTaskDefinition } from "hardhat/types/tasks";
import type { PluginTaskDefinition } from "hardhat/types/plugins";

import { task } from "hardhat/config";

Expand All @@ -7,7 +7,7 @@ import {
extendWithVerificationArgs,
} from "../utils.js";

const verifySourcifyTask: NewTaskDefinition = extendWithSourcifyArgs(
const verifySourcifyTask: PluginTaskDefinition = extendWithSourcifyArgs(
extendWithVerificationArgs(
task(["verify", "sourcify"], "Verify a contract on Sourcify"),
),
Expand Down
63 changes: 48 additions & 15 deletions v-next/hardhat/src/internal/core/config-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import {
} from "../../types/arguments.js";
import {
type EmptyTaskDefinition,
TaskDefinitionType,
type NewTaskDefinition,
type TaskDefinition,
TaskDefinitionType,
type TaskOverrideDefinition,
} from "../../types/tasks.js";

Expand Down Expand Up @@ -272,13 +272,7 @@ export function validateNewTask(
});
}

if (typeof task.action !== "function") {
validationErrors.push({
path: [...path, "action"],
message:
"task action must be a lazy import function returning a module with a default export",
});
}
validationErrors.push(...validateActionFields(task, path));

if (isObject(task.options)) {
validationErrors.push(
Expand Down Expand Up @@ -328,13 +322,7 @@ export function validateTaskOverride(
});
}

if (typeof task.action !== "function") {
validationErrors.push({
path: [...path, "action"],
message:
"task action must be a lazy import function returning a module with a default export",
});
}
validationErrors.push(...validateActionFields(task, path));

if (isObject(task.options)) {
validationErrors.push(
Expand All @@ -350,6 +338,51 @@ export function validateTaskOverride(
return validationErrors;
}

function validateActionFields(
task: { action?: unknown; inlineAction?: unknown },
path: Array<string | number>,
): HardhatUserConfigValidationError[] {
const validationErrors: HardhatUserConfigValidationError[] = [];

// Mutual exclusivity: cannot have both action and inlineAction
if (task.action !== undefined && task.inlineAction !== undefined) {
validationErrors.push({
path: [...path],
message: 'task cannot define both "action" and "inlineAction"',
});
}

// At least one action must be defined
if (task.action === undefined && task.inlineAction === undefined) {
validationErrors.push({
path: [...path, "action"],
message: 'task must define either "action" or "inlineAction"',
});
}

if (task.action !== undefined) {
if (typeof task.action !== "function") {
validationErrors.push({
path: [...path, "action"],
message:
"task action must be a lazy import function returning a module with a default export",
});
}
}

if (task.inlineAction !== undefined) {
if (typeof task.inlineAction !== "function") {
validationErrors.push({
path: [...path, "inlineAction"],
message:
"task inlineAction must be a function implementing the task's behavior",
});
}
}

return validationErrors;
}

export function validateOptions(
options: Record<string, OptionDefinition>,
path: Array<string | number>,
Expand Down
Loading
Loading