# 整個 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入面.

github artifact 係github action入面比你output file既方法

create 個job status 既file,之後用github mini action去upload個job status到 github artifact,暫時未知有咩用,應該只係for 之後debug之用

### 流程
```
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同

改manifest repo name, 呢個repo未起既,改定先,(呢part係for當呢個repo有野改之後可以更新manifest個repo values.yaml中既image tag)

之後應該可以Trigger個pipeline去build個image出黎
個github action啲harbor (for store 個docker image)secret 係action secret度Set既


## 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

係啲env example 度揾呢個application 要啲咩environment variable

同樣可以係config.ts 度呢個application 要啲咩environment variable

啲environment variable 可能要自己揾返,例如Mongo呢個可以係Rancher 度揾度揾到

知道個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既

改service account.yaml

改Service.yaml

改ingress,yaml

改hpa.yaml

改development.yaml

改完之後試下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 哥個去個

改返namespaces, repo link

```
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應該會睇到
