11import { task } from 'hardhat/config'
2- import type { ActionType } from 'hardhat/types'
2+ import type { ActionType , HardhatRuntimeEnvironment } from 'hardhat/types'
33import { TASK_COMPILE } from 'hardhat/builtin-tasks/task-names'
44import { TASK_LZ_DEPLOY } from '@/constants/tasks'
55import {
@@ -17,11 +17,57 @@ import { formatEid } from '@layerzerolabs/devtools'
1717import { getEidsByNetworkName , getHreByNetworkName } from '@/runtime'
1818import { types } from '@/cli'
1919import { promptForText } from '@layerzerolabs/io-devtools'
20- import { Deployment } from 'hardhat-deploy/dist/types'
20+ import { Deployment , DeployFunction } from 'hardhat-deploy/dist/types'
2121import { assertDefinedNetworks , assertHardhatDeploy } from '@/internal/assertions'
2222import { splitCommaSeparated } from '@layerzerolabs/devtools'
2323import { isDeepEqual } from '@layerzerolabs/devtools'
2424import { Stage , endpointIdToStage } from '@layerzerolabs/lz-definitions'
25+ import { readdirSync , statSync } from 'fs'
26+ import { join , extname } from 'path'
27+
28+ /**
29+ * Get all available tags from deploy scripts in the given deploy paths.
30+ * Uses require() with ts-node/esm loader to handle TypeScript files.
31+ */
32+ const getAvailableTagsFromDeployScripts = async ( hre : HardhatRuntimeEnvironment ) : Promise < Set < string > > => {
33+ const tags = new Set < string > ( )
34+ const deployPaths = hre . config . paths . deploy
35+
36+ for ( const deployPath of deployPaths ) {
37+ try {
38+ const files = readdirSync ( deployPath )
39+ for ( const file of files ) {
40+ const filePath = join ( deployPath , file )
41+ // Skip directories and non-script files
42+ if ( statSync ( filePath ) . isDirectory ( ) ) {
43+ continue
44+ }
45+ const ext = extname ( file )
46+ if ( ! [ '.js' , '.ts' ] . includes ( ext ) ) {
47+ continue
48+ }
49+
50+ try {
51+ // Use require which works with ts-node/register in hardhat context
52+ // eslint-disable-next-line @typescript-eslint/no-var-requires
53+ const deployScript = require ( filePath )
54+ const deployFunc : DeployFunction = deployScript . default ?? deployScript
55+ if ( deployFunc ?. tags ) {
56+ for ( const tag of deployFunc . tags ) {
57+ tags . add ( tag )
58+ }
59+ }
60+ } catch {
61+ // Skip files that can't be imported
62+ }
63+ }
64+ } catch {
65+ // Skip paths that don't exist
66+ }
67+ }
68+
69+ return tags
70+ }
2571
2672interface TaskArgs {
2773 networks ?: string [ ]
@@ -166,6 +212,16 @@ const action: ActionType<TaskArgs> = async (
166212 logger . warn ( `Will use all deployment scripts` )
167213 } else {
168214 logger . info ( `Will use deploy scripts tagged with ${ selectedTags . join ( ', ' ) } ` )
215+
216+ // Check if selected tags match any available deploy script tags
217+ const availableTags = await getAvailableTagsFromDeployScripts ( hre )
218+ const unmatchedTags = selectedTags . filter ( ( tag ) => ! availableTags . has ( tag ) )
219+
220+ if ( unmatchedTags . length > 0 ) {
221+ logger . warn (
222+ `The following tags do not match any deploy scripts: ${ unmatchedTags . join ( ', ' ) } . Available tags: ${ [ ...availableTags ] . join ( ', ' ) || 'none' } `
223+ )
224+ }
169225 }
170226
171227 // Now we confirm with the user that they want to continue
@@ -261,8 +317,23 @@ const action: ActionType<TaskArgs> = async (
261317 error == null ? [ ] : [ { networkName, error } ]
262318 )
263319
264- // If nothing went wrong we just exit
320+ // We check whether any contracts were actually deployed
321+ const totalContractsDeployed = Object . values ( results ) . reduce (
322+ ( sum , { contracts } ) => sum + Object . keys ( contracts ?? { } ) . length ,
323+ 0
324+ )
325+
326+ // If nothing went wrong we check if any contracts were deployed
265327 if ( errors . length === 0 ) {
328+ if ( totalContractsDeployed === 0 ) {
329+ return (
330+ logger . warn (
331+ `${ printBoolean ( false ) } No contracts were deployed. This could mean the deploy script tags don't match any scripts, or all contracts were already deployed.`
332+ ) ,
333+ results
334+ )
335+ }
336+
266337 return logger . info ( `${ printBoolean ( true ) } Your contracts are now deployed` ) , results
267338 }
268339
0 commit comments