It could not find the build from frontendapp when I tried to run cdk deploy on GitHub Actions. I checked the path for build and it seems to be no issues. I tried running cdk deploy --all
locally and it works when I open the website that shows the content from the frontendapp/build.
Error message:
Run cdk deploy --all
/home/runner/work/CDK_Test/CDK_Test/node_modules/aws-cdk-lib/core/lib/asset-staging.js:1
"use strict";var _a;Object.defineProperty(exports,"__esModule",{value:!0}),exports.AssetStaging=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var crypto=()=>{var tmp=require("crypto");return crypto=()=>tmp,tmp},path=()=>{var tmp=require("path");return path=()=>tmp,tmp},constructs_1=()=>{var tmp=require("constructs");return constructs_1=()=>tmp,tmp},fs=()=>{var tmp=require("fs-extra");return fs=()=>tmp,tmp},assets_1=()=>{var tmp=require("./assets");return assets_1=()=>tmp,tmp},bundling_1=()=>{var tmp=require("./bundling");return bundling_1=()=>tmp,tmp},fs_1=()=>{var tmp=require("./fs");return fs_1=()=>tmp,tmp},fingerprint_1=()=>{var tmp=require("./fs/fingerprint");return fingerprint_1=()=>tmp,tmp},names_1=()=>{var tmp=require("./names");return names_1=()=>tmp,tmp},asset_staging_1=()=>{var tmp=require("./private/asset-staging");return asset_staging_1=()=>tmp,tmp},cache_1=()=>{var tmp=require("./private/cache");return cache_1=()=>tmp,tmp},stack_1=()=>{var tmp=require("./stack");return stack_1=()=>tmp,tmp},stage_1=()=>{var tmp=require("./stage");return stage_1=()=>tmp,tmp},cxapi=()=>{var tmp=require("../../cx-api");return cxapi=()=>tmp,tmp};const ARCHIVE_EXTENSIONS=[".tar.gz",".zip",".jar",".tar",".tgz"],ASSET_SALT_CONTEXT_KEY="@aws-cdk/core:assetHashSalt";class AssetStaging extends constructs_1().Construct{static clearAssetHashCache(){this.assetCache.clear(),(0,fingerprint_1().clearLargeFileFingerprintCache)()}constructor(scope,id,props){super(scope,id);try{jsiiDeprecationWarnings().aws_cdk_lib_AssetStagingProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,AssetStaging),error}const salt=this.node.tryGetContext(ASSET_SALT_CONTEXT_KEY);if(this.sourcePath=path().resolve(props.sourcePath),this.fingerprintOptions={...props,exclude:[".is_custom_resource",...props.exclude??[]],extraHash:props.extraHash||salt?`${props.extraHash??""}${salt??""}`:void 0},!fs().existsSync(this.sourcePath))throw new Error(`Cannot find asset at ${this.sourcePath}`);this.sourceStats=fs().statSync(this.sourcePath);const outdir=stage_1().Stage.of(this)?.assetOutdir;if(!outdir)throw new Error('unable to determine cloud assembly asset output directory. Assets must be defined indirectly within a "Stage" or an "App" scope');this.assetOutdir=outdir,this.customSourceFingerprint=props.assetHash,this.hashType=determineHashType(props.assetHashType,this.customSourceFingerprint);let stageThisAsset,skip=!1;if(props.bundling){skip=!stack_1().Stack.of(this).bundlingRequired;const bundling=props.bundling;stageThisAsset=()=>this.stageByBundling(bundling,skip)}else stageThisAsset=()=>this.stageByCopying();this.cacheKey=calculateCacheKey({outdir:this.assetOutdir,sourcePath:path().resolve(props.sourcePath),bundling:props.bundling,assetHashType:this.hashType,customFingerprint:this.customSourceFingerprint,extraHash:props.extraHash,exclude:props.exclude,ignoreMode:props.ignoreMode,skip});const staged=AssetStaging.assetCache.obtain(this.cacheKey,stageThisAsset);this.stagedPath=staged.stagedPath,this.absoluteStagedPath=staged.stagedPath,this.assetHash=staged.assetHash,this.packaging=staged.packaging,this.isArchive=staged.isArchive}get sourceHash(){return this.assetHash}relativeStagedPath(stack){try{jsiiDeprecationWarnings().aws_cdk_lib_Stack(stack)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.relativeStagedPath),error}const asmManifestDir=stage_1().Stage.of(stack)?.outdir;return asmManifestDir?path().relative(this.assetOutdir,this.stagedPath).startsWith("..")||this.stagingDisabled?this.stagedPath:path().relative(asmManifestDir,this.stagedPath):this.stagedPath}stageByCopying(){const assetHash=this.calculateHash(this.hashType),stagedPath=this.stagingDisabled?this.sourcePath:path().resolve(this.assetOutdir,renderAssetFilename(assetHash,getExtension(this.sourcePath)));if(!this.sourceStats.isDirectory()&&!this.sourceStats.isFile())throw new Error(`Asset ${this.sourcePath} is expected to be either a directory or a regular file`);return this.stageAsset(this.sourcePath,stagedPath,"copy"),{assetHash,stagedPath,packaging:this.sourceStats.isDirectory()?assets_1().FileAssetPackaging.ZIP_DIRECTORY:assets_1().FileAssetPackaging.FILE,isArchive:this.sourceStats.isDirectory()||ARCHIVE_EXTENSIONS.includes(getExtension(this.sourcePath).toLowerCase())}}stageByBundling(bundling,skip){if(!this.sourceStats.isDirectory())throw new Error(`Asset ${this.sourcePath} is expected to be a directory when bundling`);if(skip){let hashType=this.hashType;return(hashType===assets_1().AssetHashType.OUTPUT||hashType===assets_1().AssetHashType.BUNDLE)&&(this.customSourceFingerprint=names_1().Names.uniqueId(this),hashType=assets_1().AssetHashType.CUSTOM),{assetHash:this.calculateHash(hashType,bundling),stagedPath:this.sourcePath,packaging:assets_1().FileAssetPackaging.ZIP_DIRECTORY,isArchive:!0}}let assetHash=this.hashType===assets_1().AssetHashType.SOURCE||this.hashType===assets_1().AssetHashType.CUSTOM?this.calculateHash(this.hashType,bundling):void 0;const bundleDir=this.determineBundleDir(this.assetOutdir,assetHash);this.bundle(bundling,bundleDir);const bundlingOutputType=bundling.outputType??bundling_1().BundlingOutput.AUTO_DISCOVER,bundledAsset=determineBundledAsset(bundleDir,bundlingOutputType);assetHash=assetHash??this.calculateHash(this.hashType,bundling,bundledAsset.path);const stagedPath=path().resolve(this.assetOutdir,renderAssetFilename(assetHash,bundledAsset.extension));return this.stageAsset(bundledAsset.path,stagedPath,"move"),bundledAsset.packaging===assets_1().FileAssetPackaging.FILE&&(this.hashType===assets_1().AssetHashType.OUTPUT||this.hashType===assets_1().AssetHashType.BUNDLE?fs().removeSync(path().dirname(bundledAsset.path)):fs().closeSync(fs().openSync(bundledAsset.path,"w"))),{assetHash,stagedPath,packaging:bundledAsset.packaging,isArchive:bundlingOutputType!==bundling_1().BundlingOutput.SINGLE_FILE}}get stagingDisabled(){return!!this.node.tryGetContext(cxapi().DISABLE_ASSET_STAGING_CONTEXT)}stageAsset(sourcePath,targetPath,style){if(fs().existsSync(targetPath)){style==="move"&&sourcePath!==targetPath&&fs().removeSync(sourcePath);return}if(style=="move"){fs().renameSync(sourcePath,targetPath);return}if(this.sourceStats.isFile())fs().copyFileSync(sourcePath,targetPath);else if(this.sourceStats.isDirectory())fs().mkdirSync(targetPath),fs_1().FileSystem.copyDirectory(sourcePath,targetPath,this.fingerprintOptions);else throw new Error(`Unknown file type: ${sourcePath}`)}determineBundleDir(outdir,sourceHash){return sourceHash?path().resolve(outdir,renderAssetFilename(sourceHash)):path().resolve(outdir,`bundling-temp-${this.cacheKey}`)}bundle(options,bundleDir){if(fs().existsSync(bundleDir))return;fs().ensureDirSync(bundleDir),fs().chmodSync(bundleDir,511);let localBundling;try{if(process.stderr.write(`Bundling asset ${this.node.path}...
^
Error: Cannot find asset at /home/runner/work/CDK_Test/CDK_Test/frontend/frontendapp/build
at new AssetStaging (/home/runner/work/CDK_Test/CDK_Test/node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:2119)
at new Asset (/home/runner/work/CDK_Test/CDK_Test/node_modules/aws-cdk-lib/aws-s3-assets/lib/asset.js:1:1141)
at Object.bind (/home/runner/work/CDK_Test/CDK_Test/node_modules/aws-cdk-lib/aws-s3-deployment/lib/source.js:1:1460)
at /home/runner/work/CDK_Test/CDK_Test/node_modules/aws-cdk-lib/aws-s3-deployment/lib/bucket-deployment.js:1:3768
at Array.map (<anonymous>)
at new BucketDeployment (/home/runner/work/CDK_Test/CDK_Test/node_modules/aws-cdk-lib/aws-s3-deployment/lib/bucket-deployment.js:1:3749)
at new FrontendStack (/home/runner/work/CDK_Test/CDK_Test/cdk/lib/cdk_test-frontend-stack.ts:70:3)
at new AppStack (/home/runner/work/CDK_Test/CDK_Test/cdk/lib/cdk_test-app-stack.ts:11:27)
at Object.<anonymous> (/home/runner/work/CDK_Test/CDK_Test/cdk/lib/cdk_test-app-stack.ts:32:1)
at Module._compile (node:internal/modules/cjs/loader:1358:14)
Subprocess exited with error 1
Error: Process completed with exit code 1.
.github/workflows/deploy.yml:
name: Deploy to AWS
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
env:
AWS_REGION: 'us-east-1'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Install AWS CDK
run: npm install -g aws-cdk
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{secrets.ROLE_TO_ASSUME}}
aws-region: ${{ env.AWS_REGION }}
role-session-name: GitHubActions
- name: CDK deploy
run: cdk deploy --all
- name: Run Sequelize commands
env:
DB_USERNAME: ${{ secrets.USERNAME }}
DB_PASSWORD: ${{ secrets.PASSWORD }}
DB_NAME: ${{ secrets.DATABASE }}
DB_HOST: ${{ secrets.HOST }}
run: |
npx sequelize db:migrate
cdk/lib/cdk_test-frontend-stack.ts snippet codes:
const distribution = new cloudfront.CloudFrontWebDistribution(
this,
"cloudfront",
{
originConfigs: [
{
s3OriginSource: {
s3BucketSource: websiteBucket,
originAccessIdentity: identity,
},
behaviors: [
{
viewerProtocolPolicy:
cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
allowedMethods: cloudfront.CloudFrontAllowedMethods.GET_HEAD,
compress: true,
isDefaultBehavior: true,
},
],
},
],
defaultRootObject: "./frontend/frontendapp/build/index.html",
}
);
new s3deploy.BucketDeployment(this, "DeployWebsite", {
sources: [s3deploy.Source.asset("./frontend/frontendapp/build")],
destinationBucket: websiteBucket,
distribution,
});
frontend/frontendapp/build - listing the files and directory under build:
- static (dir)
- asset-manifest.json
- favicon.ico
- index.html
- logo512.png
- manifest.json
- robots.txt
I have tried running npm run build
inside frontend/frontendapp before pushing to GitHub, where it automates deployment with CDK. However, the deployment failed. Do you have any suggestions or solutions for this? Thank you in advance.
I believe your problem will be solved if you:
frontend
and cdk
. Each directory should have its own package.json
and package-lock.json
, or the equivalent files if you're using something other than npm.working-directory: cdk
to your Actions steps named Install dependencies
and CDK deploy
.CDK deploy
step, like
- name: Install frontend
working-directory: frontend
run: npm install
- name: Build frontend
working-directory: frontend
run: npm run build
- name: Test frontend
working-directory: frontend
run: npm test
I think this is the most significant missing piece. Without npm run build
happening for the frontend code on your Actions runner, the build/
directory isn't populated. The build/
artifact is probably ignored by Git, because its contents are created from other files and so should not be in source control. So even if you run npm run build
before pushing, the files aren't available within Actions.sources: [s3deploy.Source.asset("./frontend/frontendapp/build")],
to sources: [s3deploy.Source.asset("../frontend/frontendapp/build")],
changing the path prefix from .
to ..
.You may need some minor adjustments, for example if you have your package.json
in frontend/frontendapp/
rather than in frontend/
, but I believe it will all work if you do the steps above.
I find it better to have separate package.json
s for CDK code and frontend code because:
npm
commands target the right project, and that build artifacts include the right files.I have one of my projects set up very similarly to yours, using the recommendations above, and its deployment works successfully. The project is at https://github.com/douglasnaphas/anagrampoems.
You could probably ignore all my recommendations except for adding an npm run build
GitHub Actions step for the frontend code, as long as you make sure it's happening in the right directory.