在 GitHub Action 上运行 CDK 部署时,无法在 /home/runner/CDK_Test/frontend/frontendapp/build 找到资产

问题描述 投票:0回答:1

当我尝试在 GitHub Actions 上运行 cdk deploy 时,它无法从 frontendapp 找到构建。我检查了构建路径,似乎没有问题。我尝试在本地运行

cdk deploy --all
,当我打开显示 frontendapp/build 内容的网站时它就可以工作。

错误信息:

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 片段代码:

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 - 列出构建下的文件和目录:

- static (dir)
- asset-manifest.json
- favicon.ico
- index.html
- logo512.png
- manifest.json
- robots.txt

在推送到 GitHub 之前,我尝试在 frontend/frontendapp 中运行

npm run build
,它会使用 CDK 自动进行部署。然而,部署失败。您对此有什么建议或解决方案吗?预先感谢您。

typescript amazon-s3 github-actions amazon-cloudfront aws-cdk
1个回答
0
投票

我相信如果您满足以下条件,您的问题就会得到解决:

  1. 确保您有单独的
    frontend
    cdk
    包。每个目录都应该有自己的
    package.json
    package-lock.json
    ,或者如果您使用的是 npm 以外的其他文件,则应有等效文件。
  2. working-directory: cdk
    添加到名为
    Install dependencies
    CDK deploy
    的操作步骤中。
  3. CDK deploy
    步骤之前将前端安装、构建和测试步骤添加到操作文件中,例如
    - 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
    
    我认为这是最重要的缺失部分。如果 Actions 运行器上的前端代码没有发生
    npm run build
    ,则不会填充
    build/
    目录。 Git 可能会忽略
    build/
    工件,因为它的内容是从其他文件创建的,因此不应位于源代码管理中。因此,即使您在推送之前运行
    npm run build
    ,这些文件在操作中也不可用。
  4. sources: [s3deploy.Source.asset("./frontend/frontendapp/build")],
    更改为
    sources: [s3deploy.Source.asset("../frontend/frontendapp/build")],
    ,将路径前缀从
    .
    更改为
    ..

您可能需要一些细微的调整,例如,如果您将

package.json
放在
frontend/frontendapp/
中而不是
frontend/
中,但我相信如果您执行上述步骤,一切都会起作用。

我发现 CDK 代码和前端代码最好有单独的

package.json
,因为:

  1. 它们是单独的包。一个的依赖关系不是另一个的依赖关系。
  2. 它避免了尝试确保
    npm
    命令针对正确的项目,并且构建工件包含正确的文件的混乱。

我的一个项目的设置与您的项目非常相似,使用上述建议,并且其部署成功。该项目位于 https://github.com/douglasnaphas/anagrampoems

您可能会忽略我的所有建议,除了为前端代码添加

npm run build
GitHub Actions 步骤,只要您确保它发生在正确的目录中即可。

© www.soinside.com 2019 - 2024. All rights reserved.