gitlab java ci/cd

stages:
  - build
  - package
  - deploy
  - upload-jar

variables:
  MAVEN_CLI_OPTS: -s .m2/settings.xml --batch-mode
  PROJECTS: bike-ca-client,bike-ca-webapi,bike-ca-model

maven-build:
  stage: build
  script:
    - mvn clean package -am -pl bike-ca-web -DskipTests
  artifacts:
    paths:
      - bike-ca-web/target/*.zip
    expire_in: 30 mins
  only:
    - develop
    - /^feature\/.*/
    - /^hotfix\/.*/
    - /^release\/.*/


#上传jar包到私服
maven-deploy:
  stage: upload-jar
  script: mvn $MAVEN_CLI_OPTS -am -pl $PROJECTS source:jar deploy
  only:
    - develop
    - /^feature\/.*/
    - /^hotfix\/.*/
    - /^release\/.*/

docker-build:
  stage: package
  dependencies:
    - maven-build
  script:
    - mkdir app && bsdtar --strip-components=1 -xvf bike-ca-web/target/bike-ca-web-0.0.1-SNAPSHOT.zip -C app
    - chmod +x app/run.sh
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  only:
    - develop
    - /^feature\/.*/
    - /^hotfix\/.*/
    - /^release\/.*/

kubernetes-deploy:
  stage: deploy
  dependencies: []
  variables:
    APP_NAME: bike-ca
    SERVER_PORT: 8084
  script:
    - >
      bash <(curl -H "Private-Token: $PRIVATE_TOKEN" \
        https://git.jintdev.com/api/v4/projects/72/repository/files/nest-deploy.sh/raw?ref=master) | \
      kubectl apply -n $K8S_NAMESPACE -f -
  only:
    - develop
    - /^feature\/.*/
    - /^hotfix\/.*/
    - /^release\/.*/

# TAG 触发正式编译与打包
maven-tag-build:
  stage: build
  script:
    - mvn clean package -DskipTests
  artifacts:
    paths:
      - bike-ca-web/target/*.zip
    expire_in: 30 mins
  only:
    - tags

docker-tag-build:
  stage: package
  dependencies:
    - maven-tag-build
  script:
    - mkdir app && bsdtar --strip-components=1 -xvf bike-ca-web/target/bike-ca-web-0.0.1-SNAPSHOT.zip -C app
    - chmod +x app/run.sh
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
  only:
    - tags



k8s java ci/cd 部署脚本
#!/bin/bash

[ -z $REPLICAS ] && REPLICAS=1
[ -z $IMAGE ] && IMAGE=$CI_REGISTRY_IMAGE
REDEPLOY=$([ -n $CI_COMMIT_SHA ] && echo $CI_COMMIT_SHA || echo "dev")
# 设置SpringBoot默认 configMap
[ -z $APPLICATION_CONFIG ] && APPLICATION_CONFIG='default-config'

if [ -n "$VERSION" ]; then
  VERSION=$VERSION
elif [ -n "$CI_COMMIT_TAG" ]; then
  VERSION=$CI_COMMIT_TAG
elif [ -n "$CI_COMMIT_REF_SLUG" ]; then
  VERSION=$CI_COMMIT_REF_SLUG
fi

if [[ $APP_NAME == "" || $IMAGE == "" || $VERSION == "" || $SERVER_PORT == "" ]]; then
  echo "missing APP_NAME IMAGE VERSION or SERVER_PORT"; exit 2
fi

cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ${APP_NAME}
    version: ${VERSION}
  name: ${APP_NAME}-${VERSION}
spec:
  replicas: ${REPLICAS}
  revisionHistoryLimit: 5
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  selector:
    matchLabels:
      app: ${APP_NAME}
      version: ${VERSION}
  template:
    metadata:
      annotations:
        co.elastic.logs/enabled: "true"
        co.elastic.logs/multiline.pattern: '^\d{2}:\d{2}:\d{2}'
        co.elastic.logs/multiline.negate: "true"
        co.elastic.logs/multiline.match: "after"
        co.elastic.logs.istio-proxy/enabled: "false"
      labels:
        app: ${APP_NAME}
        version: ${VERSION}
    spec:
      containers:
      - name: ${APP_NAME}
        image: ${IMAGE}:${VERSION}
        imagePullPolicy: Always
        env:
        - name: NEST_HOME
          value: /nest
        - name: SPRING_CONFIG_LOCATION
          value: classpath:/,classpath:/config/,file:./,file:./config/,/config/
        - name: SPRING_PROFILES_ACTIVE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: FOR_GODS_SAKE_PLEASE_REDEPLOY
          value: '${REDEPLOY}'
        - name: JAVA_OPTS
          value: -server -XX:+UseParallelGC -XX:+UseParallelOldGC -Dons.client.logFileMaxIndex=1 -Drocketmq.client.logUseSlf4j=true
        volumeMounts:
        - name: config-volume
          mountPath: /nest/config
        - name: spring-config
          mountPath: /config
        ports:
        - name: http
          containerPort: ${SERVER_PORT}
        resources:
          requests:
            memory: 512Mi
        livenessProbe:
          failureThreshold: 5
          httpGet:
            path: /heatbeat
            port: http
            scheme: HTTP
          initialDelaySeconds: 15
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 2
        readinessProbe:
          failureThreshold: 5
          httpGet:
            path: /heatbeat
            port: http
            scheme: HTTP
          initialDelaySeconds: 15
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 2
      imagePullSecrets:
      - name: jintdev
      volumes:
      - name: config-volume
        configMap:
          name: nesthome-config
      - name: spring-config
        configMap:
          name: $APPLICATION_CONFIG
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ${APP_NAME}
  name: ${APP_NAME}
  annotations:
    prometheus.io/scrape: 'true'
    prometheus.io/port: '11111'
spec:
  ports:
  - name: http
    port: 80
    targetPort: http
  selector:
    app: ${APP_NAME}
  type: ClusterIP
EOF