GoogleCloudPlatform / functions-framework-nodejs

FaaS (Function as a service) framework for writing portable Node.js functions
Apache License 2.0
1.29k stars 160 forks source link

What is the proper way to configure CI/CD pipelines for deploying TS function into Google cloud functions? #528

Closed Sarnith closed 1 year ago

Sarnith commented 1 year ago

I have my cloud function written in typescript and I have configured my CI CD pipelines in Azure devops.

Below is my Package.json

{
    "name": "app-container-node",
    "version": "1.0.0",
    "description": "",
    "main": "server.js",
    "scripts": {
        "start": "node build/server.js",
        "test": "jest",
        "build": "tsc -b tsconfig.json",
        "debug": "nodemon —inspect src/server.ts",
        "copyMySpecialFiles": "copyfiles —error konnectors/**/*.js build"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "konnectify-framework": "^0.0.6",
        "body-parser": "^1.19.0",
        "btoa": "^1.2.1",
        "class-transformer": "^0.2.3",
        "class-validator": "^0.12.2",
        "cors": "^2.8.5",
        "cross-env": "^7.0.3",
        "dotenv": "^8.2.0",
        "express": "^4.17.1",
        "hawk": "^9.0.0",
        "helmet": "^4.2.0",
        "lodash": "^4.17.20",
        "moment": "^2.29.1",
        "multer": "^1.4.2",
        "nanoid": "^3.1.20",
        "reflect-metadata": "^0.1.13",
        "request": "^2.88.2",
        "routing-controllers": "^0.9.0-alpha.6",
        "ts-node": "^10.8.0",
        "typedi": "^0.8.0"
    },
    "devDependencies": {
        "@types/body-parser": "^1.19.0",
        "@types/btoa": "^1.2.3",
        "@types/cors": "^2.8.9",
        "@types/dotenv": "^8.2.0",
        "@types/express": "^4.17.9",
        "@types/hapi__hawk": "^8.0.1",
        "@types/helmet": "^4.0.0",
        "@types/jest": "^26.0.21",
        "@types/lodash": "^4.14.168",
        "@types/multer": "^1.4.5",
        "@types/node": "^14.14.16",
        "copyfiles": "^2.4.1",
        "jest": "^26.6.3",
        "jest-mock-extended": "^1.0.13",
        "nodemon": "^2.0.6",
        "ts-jest": "^26.5.4",
        "ts-loader": "^6.2.2",
        "typescript": "^4.1.3"
    }
}

This is my Azure pipelines.yml file


steps:
- task: NodeTool@0
  inputs:
    versionSpec: '10.x'
  displayName: 'Install Node.js'

- script: |
    rm ./package-lock.json
    npm cache clear -f
  displayName: 'remove package json and clear npm cache'

- task: npmAuthenticate@0
  inputs:
    workingFile: './.npmrc'

- script: |
    npm install
    npm run build
  displayName: 'npm install and build'

- task: CopyFiles@2
  displayName: 'Copy Files to: $(Build.DefaultWorkingDirectory)/build'
  inputs:
    Contents: |
      $(System.DefaultWorkingDirectory)/package.json
      $(System.DefaultWorkingDirectory)/package-lock.json
      $(System.DefaultWorkingDirectory)/.npmrc
    TargetFolder: '$(System.DefaultWorkingDirectory)/build'
    flattenFolders: true

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)/build'

And From the build folder, I am executing the following command gcloud functions deploy $(DEV_APP_ID) --runtime nodejs14 --trigger-http --entry-point app Though my code is already compiled into js, the cloud build logs, i can see that it is trying to compile the code again and failing everytime.

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: > app-container-node@1.0.0 build /workspace
> tsc -b tsconfig.json
error TS5083: Cannot read file '/workspace/tsconfig.json'.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! app-container-node@1.0.0 build: `tsc -b tsconfig.json`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the app-container-node@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR!     /www-data-home/.npm/_logs/2023-04-27T17_59_07_566Z-debug.log; Error ID: 1a2262f3

So What is the proper way to configure CI/CD pipelines for GCF?

kenneth-rosario commented 1 year ago

Hello Sarnith,

Please refer to https://cloud.google.com/functions/docs/release-notes#April_11_2023 for details on how to solve your current issue.

In summary, a new breaking change was added to the node js builders such that if the function author has a build in their package.json the builder will use npm run build to build the function source. In your case the builder is trying to run tsc -b tsconfig.json1 as specified in your package.json. The link provided has the info needed to opt out from this behavior.

Hope this helps!

kenneth-rosario commented 1 year ago

Closing for now, but feel free to reopen if this issue persists and I will assist you further.