有时候nodejs构建死活不通过,可以加个参数选择true还是false,在构建前进行彻底删除缓存,npm cache clean --force

pipeline {
  agent {
    node {
      label 'nodejs-18.16.0'
    }

  }
  stages {
    stage('编译信息') {
      steps {
        script {
          env.FULL_VERSION_NUMBER="${params.INPUT_VERSION_NUMBER}"
          env.CHOICE_PUBLISH_ENV="${params.CHOICE_PUBLISH_ENV}"
          env.VERSION_NUMBER=sh(returnStdout: true, script: 'echo ${FULL_VERSION_NUMBER#*-}').trim()
          if(params.CHOICE_PUBLISH_ENV != 'UAT-CD') {
            env.YAML_VERSION=sh(returnStdout: true, script: 'echo ${VERSION_NUMBER}.${BUILD_NUMBER}').trim()
          }else{
            env.YAML_VERSION="${params.INPUT_IMAGE_VERSION}"
          }
        }

        sh '''echo "当前分支:${FULL_VERSION_NUMBER}"
echo "K8S运行版本:${YAML_VERSION}"  
echo "选择发布环境:${CHOICE_PUBLISH_ENV}"  
echo "代码版本号:${VERSION_NUMBER}"
echo "镜像版本号:${YAML_VERSION}"
echo "===env begin==="
env
echo "===env end==="'''
      }
    }

    stage('拉取代码') {
      when {
        expression {
          env.CHOICE_PUBLISH_ENV != 'UAT-CD'
        }

      }
      steps {
        git(url: GIT_URL, credentialsId: GIT_CREDENTIAL_ID, branch: FULL_VERSION_NUMBER, changelog: true, poll: false)
      }
    }

    stage('编译构建') {
      agent none
      when {
        expression {
          env.CHOICE_PUBLISH_ENV != 'UAT-CD'
        }

      }
      steps {
        container('nodejs') {
          script {
            if (params.CLEAR_CACHE == true) {
              sh 'npm cache clean --force'
            }
          }
          sh '''npm --version
node -v
npm -v

npm config set registry https://nexus.uat.tanqidi.com/repository/npm/
echo `npm config get registry`
# npm install --ignore-scripts --prefer-offline --no-audit --verbose
npm install --ignore-scripts --verbose
echo "install finished"
npm run build
echo "build finished"'''
        }

      }
    }

    stage('打包镜像') {
      agent none
      when {
        expression {
          env.CHOICE_PUBLISH_ENV != 'UAT-CD'
        }

      }
      steps {
        container('nodejs') {
          withCredentials([usernamePassword(credentialsId : HARBOR_LOGIN_CREDENTIAL_ID ,passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,)]) {
            sh '''echo "$DOCKER_PASSWORD" | docker login ${HARBOR_REGISTRY} -u "$DOCKER_USERNAME" --password-stdin
docker build -f Dockerfile -t ${HARBOR_REGISTRY}/${HARBOR_NAMESPACE}/${APP_NAME}:${VERSION_NUMBER}.${BUILD_NUMBER} .
docker push ${HARBOR_REGISTRY}/${HARBOR_NAMESPACE}/${APP_NAME}:${VERSION_NUMBER}.${BUILD_NUMBER}'''
          }

        }

      }
    }

    stage('部署UAT环境') {
      agent none
      steps {
        container('nodejs') {
          withCredentials([kubeconfigFile(credentialsId : KUBECONFIG_CREDENTIAL_ID ,variable : 'KUBECONFIG')]) {
            script {
              sh "echo \'${DEPLOY_YAML}\' > tmp.yaml"
              sh "cat tmp.yaml"
              sh "envsubst < tmp.yaml | kubectl apply -f -"
            }

          }

        }

      }
    }

  }
  environment {
    GIT_URL = 'https://gitea.tanqidi.com/test/test-web.git'
    APP_NAME = 'test-web'
    APP_ID = 'test-web'
    APOLLO_TOKEN = '123456'
    HARBOR_NAMESPACE = 'test'
    GIT_CREDENTIAL_ID = 'gitea-token'
    KUBECONFIG_CREDENTIAL_ID = 'k8s-kubeconfig'
    HARBOR_LOGIN_CREDENTIAL_ID = 'harbor'
    HARBOR_PULL_CREDENTIAL_ID = 'harbor'
    HARBOR_REGISTRY = 'harbor.tanqidi.com'
    NET_NAME = 'test-web'
    DEPLOY_YAML = '''
      apiVersion: v1
      kind: Service
      metadata:
        namespace: ${HARBOR_NAMESPACE}
        name: ${APP_NAME}
      spec:
        clusterIP: None
        ports:
        - port: 80
          targetPort: 80
          name: client 
        selector:
          app: ${APP_NAME}
---    
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        namespace: ${HARBOR_NAMESPACE}
        name: ${APP_NAME}
        labels:
          net_name: ${NET_NAME}
        annotations:
          kubesphere.io/description: \'${HARBOR_NAMESPACE}/${APP_NAME}:${YAML_VERSION}\'
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: ${APP_NAME}
        template:
          metadata:
            labels:
              app: ${APP_NAME}
              net_name: ${NET_NAME}
          spec:
            imagePullSecrets:
              - name: ${HARBOR_PULL_CREDENTIAL_ID}
            affinity:
              podAntiAffinity:
                preferredDuringSchedulingIgnoredDuringExecution:
                  - weight: 100
                    podAffinityTerm:
                      labelSelector:
                        matchExpressions:
                          - key: app
                            operator: In
                            values:
                              - ${APP_NAME}
                      topologyKey: kubernetes.io/hostname
            containers:
              - name: ${APP_NAME}
                image: ${HARBOR_REGISTRY}/${HARBOR_NAMESPACE}/${APP_NAME}:${YAML_VERSION}
                ports:
                  - containerPort: 80
                    name: client
                env:
                  - name: MY_POD_NAME
                    valueFrom:
                      fieldRef:
                        apiVersion: v1
                        fieldPath: metadata.name
                  - name: APOLLO_URL
                    value: \'http://apollo.bx.svc.cluster.local:8070\'
                  - name: APOLLO_TOKEN
                    value: ${APOLLO_TOKEN}
                  - name: APP_ID
                    value: ${APP_ID}
                  - name: ENV
                    value: \'UAT\'
                  - name: LANG
                    value: \'en_US.UTF-8\'
                volumeMounts:
                  - name: host-time
                    readOnly: true
                    mountPath: /etc/localtime
                  - name: log-host-storage
                    mountPath: /log
                    subPath: ${APP_NAME}
                resources:
                  limits:
                    cpu: \'1\'
                    memory: 1Gi
                  requests:
                    cpu: 10m
                    memory: 60Mi
                livenessProbe:
                  tcpSocket:
                    port: 80
                  initialDelaySeconds: 20
                  timeoutSeconds: 2
                  periodSeconds: 10
                  failureThreshold: 3
                readinessProbe:
                  tcpSocket:
                    port: 80
                  initialDelaySeconds: 20
                  timeoutSeconds: 2
                  periodSeconds: 5
                  failureThreshold: 3
            volumes:
              - name: host-time
                hostPath:
                  path: /etc/localtime
                  type: \'\'
              - name: log-host-storage
                hostPath:
                  path: /log
                  type: \'\'   
'''
  }
  parameters {
    choice(name: 'CHOICE_PUBLISH_ENV', description: '请选择发布环境', choices: ['UAT-CICD', 'UAT-CD'])
    booleanParam(name: 'CLEAR_CACHE', defaultValue: false, description: '是否清空缓存')
    string(name: 'INPUT_VERSION_NUMBER', defaultValue: '', description: '请输入分支的版本,如:release-1.3.20220531')
    string(name: 'INPUT_IMAGE_VERSION', defaultValue: '', description: '请输入harbor镜像版本,如:2.1.20220609.8')
  }
}