---
# System prepended metadata

title: '整個 github action,helm chart create, argocd manifest流程'

---


# 整個 github action,helm chart create, argocd manifest流程


## 1, 跟返個repo, 加返個github action pipeline
### 解析
.github/workflows/publish-develop.yml
copy例子
https://github.com/One2Cloud/dedrive-path-based-access-gateway/blob/develop/.github/workflows/publish-develop.yml

`on`: 定義觸發自動構建的事件，本例中只有推送到 "develop" 分支時才會觸發。
`jobs` : 定義一個或多個 job（工作），每個 job 都包含一個或多個步驟（steps）。

`Checkout`: 下載代碼庫。,有左actions/checkout@v3(類似mini action,docker 官方既一堆github action既其中之一) 個github action先控制到個repo啲code

`Set up QEMU`: 設置 QEMU。
在 GitHub Action 中使用 QEMU，可以在不同的操作系統上執行和測試程式碼，特別是對於跨平台開發或測試而言。docker/setup-qemu-action 是官方提供的一個 Action，可以幫助在 GitHub Actions 上設置 QEMU，以支援 ARM 或 PowerPC 等不同的架構。

`Get Git Short SHA`：獲取 Git 短 SHA。
Git SHA 是 Git 版本控制系統中每個提交的唯一識別符號。為了方便在版本控制系統中查看不同提交的變化，可以使用 Git SHA 來區分它們。獲取 Git 短 SHA 的目的是為了將它作為 Docker 影像標籤的一部分，以便在推送 Docker 影像時可以將其版本化。通常只需要使用短 SHA，因為它是足夠唯一且易於記憶和傳遞的，而且比長 SHA 更加簡潔。

`--password-stdin`: stdin可以防止password在history中記錄

echo "${{ secrets.HARBOR_PASSWORD }}" | docker login $HARBOR_REGISTRY_URI -u ${{ secrets.HARBOR_USERNAME }} --password-stdin
這command 如何login harbor? 

這個 command 是使用 Docker CLI 登入 Harbor 容器映像倉庫。其中 secrets.HARBOR_PASSWORD 和 secrets.HARBOR_USERNAME 是 GitHub 存儲庫中保存的 Harbor 容器映像倉庫的用戶名和密碼的 secrets。$HARBOR_REGISTRY_URI 是存儲庫的 URL。具體的流程如下：

1, echo "${{ secrets.HARBOR_PASSWORD }}" 這個命令會將 Harbor 容器映像倉庫的密碼以標準輸入(stdin)的形式輸出到終端。

2, | 這個符號是管道(pipe)符號，將上一個命令的輸出作為參數傳遞到下一個命令中。

3, docker login $HARBOR_REGISTRY_URI -u ${{ secrets.HARBOR_USERNAME }} --password-stdin 這個命令會使用 Docker CLI 登入 Harbor 容器映像倉庫。$HARBOR_REGISTRY_URI 是存儲庫的 URL，secrets.HARBOR_USERNAME 是存儲庫的用戶名，--password-stdin 是指將密碼作為標準輸入的形式傳遞到 docker login 命令中。通過這種方式，Docker CLI 就可以使用提供的用戶名和密碼進行驗證，從而訪問 Harbor 容器映像倉庫中的映像。


One docker image can have mutiple tags, 於push image 前,我地先為image 加上不同的tags

update-manifest-repo-image-tag: 這個steps 我地係test helm chart之前係comment左佢先既. 之後試到個helm chart/image work之後,我地先uncomment 呢個steps. 佢係用黎係之後當呢個image repo 有野變都可以keep住update manifest呢個repo去更新個image id用既. 可以keep住用最新既image version tag係個argo cd cluster入面.
![](https://i.imgur.com/pUXbWqw.png)


github artifact 係github action入面比你output file既方法
![](https://i.imgur.com/hq0X01E.png)
create 個job status 既file,之後用github mini action去upload個job status到 github artifact,暫時未知有咩用,應該只係for 之後debug之用
![](https://i.imgur.com/S0f6gpB.png)


### 流程
```
name: Harbor Image CI

on:
  push:
    branches: [ "develop" ]

# Env variable
env:
  HARBOR_REGISTRY_URI: harbor.degital.io
  HARBOR_PROJECT: dedrive
  IMAGE_NAME: path-based-access-gateway

jobs:
  build-image-and-publish-to-harbor:
    runs-on: ubuntu-latest
    outputs:
      slug-output-sha7: ${{ steps.slug.outputs.sha7 }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Get Git Short SHA
        id: slug
        run: echo "sha7=$(echo ${{ github.sha }} | cut -c1-7)" >>$GITHUB_OUTPUT

      - name: Build Docker image
        id: build
        run: docker build . -t $IMAGE_NAME

      - name: Login to registry
        run: echo "${{ secrets.HARBOR_PASSWORD }}" | docker login $HARBOR_REGISTRY_URI -u ${{ secrets.HARBOR_USERNAME }} --password-stdin

      - name: Push image
        run: |
          IMAGE_ID=$HARBOR_REGISTRY_URI/$HARBOR_PROJECT/$IMAGE_NAME
          # Strip git ref prefix from version
          VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
          # Strip "v" prefix from tag name
          [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
          # Use Docker `latest` tag convention
          [ "$VERSION" == "master" ] && VERSION=latest
          echo IMAGE_ID=$IMAGE_ID
          echo VERSION=$VERSION
          
          docker tag $IMAGE_NAME $IMAGE_ID:${{ steps.slug.outputs.sha7 }}
          docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
          docker image push --all-tags $IMAGE_ID
      # Write Job status to file
      - name: Create file build-image-and-publish-to-harbor-job-status.txt and write the job status into it
        if: always()
        run: |
          echo '${{ github.job }} job in workflow ${{ github.workflow }} of ${{github.repository}} is ${{ job.status }}.' > build_image_and_publish_to_harbor_job_status.txt
      # Upload the Jobs status file to artifact
      - name: Upload file build_image_and_publish_to_harbor_job_status.txt as an artifact
        if: always()
        uses: actions/upload-artifact@v3
        id: job01_status_artifact
        with:
          name: job01_status_artifact
          path: build_image_and_publish_to_harbor_job_status.txt

  update-manifest-repo-image-tag:
    runs-on: ubuntu-latest
    needs: [build-image-and-publish-to-harbor]
    steps:
      # checks out to Manifest Repo
      - uses: actions/checkout@v3
        name: Checkout to manifest Repo
        with:
          repository: One2Cloud/dedrive-path-based-access-gateway-manifests
          ref: 'develop'
          submodules: false
          token: ${{ secrets.PRIVATE_TOKEN_GITHUB }}

      # Push update to Manifest repo
      - name: Update Manifest Image Tag And Push to Git repo
        run: |
          git config user.name "GitHub Actions Bot"
          git config user.email "<>"
          yq -i '.image.tag = "${{ needs.build-image-and-publish-to-harbor.outputs.slug-output-sha7 }}"' values.yaml
          git add values.yaml
          git commit -m '🚀 Update Image Version to ${{ needs.build-image-and-publish-to-harbor.outputs.slug-output-sha7 }}'
          git push
      # Write Job status to file
      - name: Create file update-manifest-repo-image-tag-job-status.txt and write the job status into it
        if: always()
        run: |
          echo '${{ github.job }} job in workflow ${{ github.workflow }} of ${{github.repository}} is ${{ job.status }}.' > update_manifest_repo_image_tag_job_status.txt
      # Upload the Jobs status file to artifact
      - name: Upload file update_manifest_repo_image_tag_job_status.txt as an artifact
        if: always()
        uses: actions/upload-artifact@v3
        id: job02_status_artifact
        with:
          name: job02_status_artifact
          path: update_manifest_repo_image_tag_job_status.txt
```

注意: 只係係develop branch!!

改image name同
![](https://i.imgur.com/lB1X8NS.png)
改manifest repo name, 呢個repo未起既,改定先,(呢part係for當呢個repo有野改之後可以更新manifest個repo values.yaml中既image tag)
![](https://i.imgur.com/Fn8kLP2.png)

之後應該可以Trigger個pipeline去build個image出黎


個github action啲harbor (for store 個docker image)secret 係action secret度Set既
![](https://i.imgur.com/ltFVrZt.png)
![](https://i.imgur.com/pIQijGd.png)


## 2, helm create chart
create 個github repo, repo名係加"-manifests"

注意:係manifest"s" 有s係尾

係local create個helm 底chart
```
helm create xxxxxxx-manifests
```


## 3, update helm chart
首先要check返呢個image到底需要啲咩variable

係index.ts度揾開左咩port
![](https://i.imgur.com/mdhg3pK.png)


係啲env example 度揾呢個application 要啲咩environment variable
![](https://i.imgur.com/wjnyBnW.png)
同樣可以係config.ts 度呢個application 要啲咩environment variable
![](https://i.imgur.com/w6YG4ze.png)

啲environment variable 可能要自己揾返,例如Mongo呢個可以係Rancher 度揾度揾到
![](https://i.imgur.com/wTaL25J.png)



知道個application要咩environment,我地將呢啲值放到secret先

放落secret.yaml度先, 再轉encode做base64 先.
注意: 要改返啱既name同namespaces
```
apiVersion: v1
kind: Secret
metadata:
  name: path-based-access-gateway-secret
  namespace: dedrive-api-access-gateway-ns
type: Opaque
data:
  MONGODB_URL: ZGV2ZWxvcG1lbnQudzNibnFuaC5tb25nb2RiLm5ldAo=
  MONGODB_USERNAME: ZGVkcml2ZV91c2Vy
  MONGODB_PASSWORD: NjN1U0pta2RiUkFiaTdjMw==
  ACCESS_GATEWAY_HOSTNAME: MTAuNDMuNTAuMTMwOjgwOTI=
```

之後用kubeseal command encrypt 啲secret

注意: 一定要連到個cluster先可以用到呢個Seal, 因為佢係用你cluster 個namespaces入面一啲cert去encrypt既.

注意: seal前既yaml一定唔可以push上github度!!!
```
kubeseal --secret-file "C:\Users\PeterChong\OneDrive\one2cloud\path_base_api\dedrive-path-based-access-gateway-manifest\templates\secret.yaml" --sealed-secret-file "C:\Users\PeterChong\OneDrive\one2cloud\path_base_api\dedrive-path-based-access-gateway-manifest\templates\sealed_secret.yaml"
```

output sample as below
```
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: path-based-access-gateway-secret
  namespace: dedrive-api-access-gateway-ns
spec:
  encryptedData:
    MONGODB_DATABASE: AgA08RXQEZx9z8dZEnKorkTllAZSUtPQ2Tx4usiUwTIhT/36XzMaZxAsRtqYFViaDSFaOPvf/oF6V+ZrmYjAR1yvLCARRtKKtFBWakaKE+lSuGH4gwUBeeMWUDe5f0cQK4JcOATWTDnoPnP1gjGp41lyoXgg9p+QIayfzhdwF1C+sqPdUmEOI537Xe2AJdZe8exd/E8d9p9O527bIQ9zAtqWZkYvFs1sErisNnYAkJZLkjBA233TkxqHGRzcA8ZprK5Hvd6fyyGKBcdxJqOPbPeh3B2y65Qr6j0lp9cDFLiQysFVT/1lMZDVh5EQLXDYJvO9tzzy39WU0uQ6KfTyR43RoIN7xLU1MiX5Rjsdh8xmMMeJIwiuKBh9TYYKk7xvhOVGJbJZeKL/+Cupgbh9qZhwrljwVb2mGLU24fmnbHiIJHf6D0P3tcDqapmRDyQ9HpkPwCo+BIoE1QfNo2rr1GojDbAHV2llZAzUp9xEVwNkONR9t4+KYdexEedlplRLiYSF6Ridj+TMS8mjg6PdFiaORpJMzUij9LUi0Oiy3ADyG6JcSC8/Qf7ZOjq7RrZ/BGdG8u0B6G/NRzESNuU9JQjuiaIniCMvpnJVbNWQQVwKrzcInC9Mo4PKKFIQIpDul0W0h1WBTI6lXX25z3VwSErdLlUzKMydTUCxO7lFPcazRkjwnXioPB6idPxmoWIeOCdZ6hSSaWRSzClnr6GNOzk=
    MONGODB_URL: AgC3nqcwAJGj9/28mgL8ssCgu8HeYpciLs5TsYdp+JJqDeWyv/RAypyrWFCq10fQ0TD/DAmEA7cSUDSS11hakstmkyEx86tafl+cxkVpeiIkEeSh2Rb0iqXh1yJsN8M0TQWjwqztR2J8qPztUh29ULIjhOKkj6X8jb83uZTy5aN0MrleaSSoBDD8CWdyd+ImPCSA0MWfJjlzpQ1eH1FC/E7xa8qWL+WhqoMUk5Y56gOO8vU8RVdl7uIa6tZ/1dm06qh1YZ91iq+Ckuqpkjk9KdPbPZ1Rd7Q2y7wa8q0QEelJmmfKmut1TFYGe+/9jVkk2XFF86H/ivkaI7yih2bcZ5cXufiWH/zLrpLr9aWKP+3/3UVnf1BEWuKYjPxmNpJkOwUzhg7YPgmmvoebYB2yr/ulAztb8qSHrpFujK+YP8TaFUxefdwGF2eBQKIJPOfX1HcbqIpN3CnTySLLsGdAXhZBZscmUKDTaPHJ1AizyXDmM2AXCmnEUmzY8LzIdsJDQ6yz63bx1ZwuZEtXndUS9KPdYtogMCIlmLQ7bmcuboU3LVnRvWLO87dlKyYKV/u5yZoYoTXvwV1NFZz77AiyJ9fZ5O8LFy7pzrLmulwkw3/o5w3v3tHzU5SOIFOiiVzezxNpmHvWJj9xZs/Df3JolA62EXsU3San7UaJyjuZ3tQHVSEgj9LbCsDq4FqE45scRlnJ0W+Kvfww8q5UMM8ze1H86ecKy9ssdgZa/ijmDkj755zAWwq5JRF1u5oxJG5b5ax1FwmYNzJUMkaaNbxzZN5X3m8NTIhtVnsy4vo/
  template:
    data: null
    metadata:
      creationTimestamp: null
      name: path-based-access-gateway-secret
      namespace: dedrive-api-access-gateway-ns
    type: Opaque
```


之後改values.yaml, values.yaml 就係入你覺得之後要重用既所有Value,例如之後要重用同一個namespace,之就用namespace value放係度, 遲下如果要改namespace既話,係呢度改就可以了,唔洗係多個地方度改幾次
port係落佢要開既port, image tag 係試緊既時候要自己手動改, 要去harbor睇返改出黎既image tag係咩,跟返.latest係唔work既
![](https://i.imgur.com/0zl5FIP.png)

改service account.yaml
![](https://i.imgur.com/wrYZFNk.png)

改Service.yaml
![](https://i.imgur.com/iudOjv2.png)

改ingress,yaml
![](https://i.imgur.com/3wAShLk.png)

改hpa.yaml
![](https://i.imgur.com/GVYkVjQ.png)


改development.yaml
![](https://i.imgur.com/f5Ds0lC.png)



改完之後試下helm install
```
 helm install dedrive-path-based-access-gateway "C:\Users\PeterChong\OneDrive\one2cloud\path_base_api\dedrive-path-based-access-gateway-manifests"
```

如果成功helm install到就整個ArgoCD manifests repo
```
helm list --all-namespaces
```


## 4. 更新ArgoCD root manifest
呢個root manifests repo,既意思係ArgoCD會check 住呢個Rrepo入面既yaml. 幫你維持住個deployment到個cluster度.
https://github.com/One2Cloud/dedrive-root-manifests

加返個yaml落,複制billing 哥個去個
![](https://i.imgur.com/g02QRzC.png)
改返namespaces, repo link
![](https://i.imgur.com/PkBbk4Z.png)
```
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
    name: dedrive-path-basedoaccess-gateway
    namespace: argocd-ns
    finalizers:
        - resources-finalizer.argocd.argoproj.io
spec:
    destination:
        server: https://AC515A06A12FCB3097F17D95D383CA33.gr7.ap-southeast-1.eks.amazonaws.com
        namespace: dedrive-path-based-access-gateway-manifests-ns
    project: dedrive-develop
    source:
        path: .
        helm:
            values: |
                pushgateway:
                  enabled: false
        repoURL: https://github.com/One2Cloud/dedrive-path-based-access-gateway-manifests
        targetRevision: "develop"
    syncPolicy:
        automated:
            prune: true
            selfHeal: true
```

refresh一下個app應該會睇到
![](https://i.imgur.com/k9eTdxX.png)
