Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ jobs:
gke-credentials: ${{ secrets.GKE_SA_KEY }}
gke-project: ${{ secrets.GKE_PROJECT }}
gh-key: ${{ secrets.GH_KEY }}
pgpasswd: ${{ secrets.PGPASSWORD }}
# cloudflare-api-token: ${{ secrets.CF_API_TOKEN }}
# cloudflare-zone-id: ${{ secrets.CF_ZONE_ID }}
195 changes: 100 additions & 95 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ on:
gh-key:
description: Github authentication key
required: true
pgpasswd:
description: PGPASSWORD
required: true
# cloudflare-api-token:
# description: Cloudflare API Token
# required: true
Expand All @@ -39,12 +42,68 @@ on:
# required: true

jobs:
meta:
name: Meta
runs-on: ubuntu-latest
outputs:
context: ${{ steps.meta.outputs.context }}
cors: ${{ steps.meta.outputs.cors }}
environment: ${{ steps.meta.outputs.environment }}
namespace: ${{ steps.meta.outputs.namespace }}
release_name: ${{ steps.meta.outputs.release_name }}
replica: ${{ steps.meta.outputs.replica }}
url: ${{ steps.meta.outputs.url }}

steps:
- name: Generate metadata
id: meta
run: |
set -o pipefail
CORS_LOCALHOST="http://localhost|https://localhost|http://localhost:3000"
if [[ "${{ github.ref }}" == 'refs/heads/main' ]]; then
# Tags are deployed in prod
CONTEXT=prod
CORS=$(echo "^https://api-platform.com|$CORS_LOCALHOST$" | sed 's/\./\\./g' )
ENVIRONMENT=prod
NAMESPACE=prod-website
RELEASE_NAME=website-prod
REPLICA=1
URL=api-platform.com
else
CONTEXT=nonprod
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
ENVIRONMENT=preview
RELEASE_NAME=pr-$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
else
ENVIRONMENT=staging
RELEASE_NAME=${{ github.ref_name }}
fi
CORS=$(echo "^https://${RELEASE_NAME}.apip.preprod-tilleuls.ovh|$CORS_LOCALHOST$" | sed 's/\./\\./g' )
NAMESPACE=nonprod-website
REPLICA=1
URL=$RELEASE_NAME.apip.preprod-tilleuls.ovh
fi
echo "context=$CONTEXT" >> "$GITHUB_OUTPUT"
echo "cors=$CORS" >> "$GITHUB_OUTPUT"
echo "environment=$ENVIRONMENT" >> "$GITHUB_OUTPUT"
echo "namespace=$NAMESPACE" >> "$GITHUB_OUTPUT"
echo "release_name=$RELEASE_NAME" >> "$GITHUB_OUTPUT"
echo "replica=$REPLICA" >> "$GITHUB_OUTPUT"
echo "url=$URL" >> "$GITHUB_OUTPUT"

cat $GITHUB_OUTPUT


deploy:
name: Deploy
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
pull-requests: 'write'
needs: ["meta"]
environment:
name: ${{ needs.meta.outputs.environment }}
steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -71,106 +130,52 @@ jobs:
helm repo add bitnami https://charts.bitnami.com/bitnami/
helm repo add stable https://charts.helm.sh/stable/
helm dependency build ./helm/api-platform
- name: Define namespace
run: |
set -o pipefail
if [[ "${{ github.ref }}" == 'refs/heads/main' ]]; then
# Tags are deployed in prod
echo "CONTEXT=prod" >> "$GITHUB_ENV"
echo "RELEASE_NAME=website-prod" >> "$GITHUB_ENV"
echo "URL=api-platform.com" >> "$GITHUB_ENV"
echo 'CORS=["https://api-platform.com", "http://localhost", "https://localhost", "http://localhost:3000"]' >> "$GITHUB_ENV"
echo "NAMESPACE=prod-website" >> "$GITHUB_ENV"
echo "REPLICA=1" >> "$GITHUB_ENV"
else
CONTEXT=nonprod
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
echo RELEASE_NAME=pr-$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH") >> "$GITHUB_ENV"
export RELEASE_NAME=pr-$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
else
echo "RELEASE_NAME=${{ github.ref_name }}" >> "$GITHUB_ENV"
export RELEASE_NAME=${{ github.ref_name }}
fi
echo "URL=$RELEASE_NAME.apip.preprod-tilleuls.ovh" >> "$GITHUB_ENV"
echo "REPLICA=1" >> "$GITHUB_ENV"
echo "NAMESPACE=nonprod-website" >> "$GITHUB_ENV"
echo 'CORS=["https://${{ env.RELEASE_NAME}}.apip.preprod-tilleuls.ovh", "http://localhost", "https://localhost", "http://localhost:3000"]' >> "$GITHUB_ENV"
fi
- name: HELM Deploy
run: |
set -o pipefail
if ! helm -n ${{ env.NAMESPACE }} status ${{ env.RELEASE_NAME }} &>/dev/null; then
JWT_PASSPHRASE=$(openssl rand -base64 32)
JWT_SECRET_KEY=$(openssl genpkey -pass file:<(echo "$JWT_PASSPHRASE") -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096)
helm upgrade ${{ env.RELEASE_NAME }} ./helm/api-platform \
--reuse-values \
--install \
--create-namespace \
--debug \
--wait \
--atomic \
--namespace=${{ env.NAMESPACE }} \
--set=app.version=${{ github.sha }} \
--set=php.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/php \
--set=php.image.tag=${{ inputs.docker-images-version }} \
--set=php.image.pullPolicy=Always \
--set=caddy.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/caddy \
--set=caddy.image.tag=${{ inputs.docker-images-version }} \
--set=caddy.image.pullPolicy=Always \
--set=pwa.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/pwa \
--set=pwa.image.tag=${{ inputs.docker-images-version }} \
--set=pwa.image.pullPolicy=Always \
--set=postgresql.image.repository=bitnamilegacy/postgresql \
--set=bucket.s3Upstream=storage.googleapis.com \
--set=bucket.s3Name=api-platform-website-v3 \
--set=service.type=NodePort \
--set=ingress.enabled=true \
--set=ingress.hosts[0].host=${{ env.URL }} \
--set=ingress.hosts[0].paths[0].path=/ \
--set=ingress.hosts[0].paths[0].pathType=ImplementationSpecific \
--set=ingress.tls[0].hosts[0]=${{ env.URL }} \
--set=ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-production \
--set=ingress.tls[0].secretName=${{ env.RELEASE_NAME }}-website-ssl \
--set=php.jwt.secretKey="$JWT_SECRET_KEY" \
--set=php.jwt.publicKey="$(openssl pkey -in <(echo "$JWT_SECRET_KEY") -passin file:<(echo "$JWT_PASSPHRASE") -pubout)" \
--set=php.jwt.passphrase=$JWT_PASSPHRASE \
--set=php.corsAllowOrigin="^$(echo "${{ join(fromJSON(env.CORS), '|') }}" | sed 's/\./\\./g')$" \
--set=php.host=${{ env.URL }} \
--set=next.rootUrl=${{ env.URL }} \
--set=github.key=${{ secrets.gh-key }} \
--set=postgresql.global.postgresql.auth.password=$(openssl rand -base64 32 | tr -d "=+/") \
--set=postgresql.global.postgresql.auth.username=website \
| sed --unbuffered '/USER-SUPPLIED VALUES/,$d'
else
helm upgrade ${{ env.RELEASE_NAME }} ./helm/api-platform \
--reuse-values \
--install \
--create-namespace \
--debug \
--wait \
--atomic \
--namespace=${{ env.NAMESPACE }} \
--set=app.version=${{ github.sha }} \
--set=php.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/php \
--set=php.image.tag=${{ inputs.docker-images-version }} \
--set=php.image.pullPolicy=Always \
--set=postgresql.image.repository=bitnamilegacy/postgresql \
--set=caddy.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/caddy \
--set=caddy.image.tag=${{ inputs.docker-images-version }} \
--set=caddy.image.pullPolicy=Always \
--set=pwa.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/pwa \
--set=pwa.image.tag=${{ inputs.docker-images-version }} \
--set=pwa.image.pullPolicy=Always \
--set=php.corsAllowOrigin="^$(echo "${{ join(fromJSON(env.CORS), '|') }}" | sed 's/\./\\./g')$" \
--set=github.key=${{ secrets.gh-key }} \
--set=next.rootUrl=${{ env.URL }} \
--set=bucket.s3Upstream=storage.googleapis.com \
--set=bucket.s3Name=api-platform-website-v3 \
| sed --unbuffered '/USER-SUPPLIED VALUES/,$d'
fi
JWT_PASSPHRASE=$(openssl rand -base64 32)
JWT_SECRET_KEY=$(openssl genpkey -pass file:<(echo "$JWT_PASSPHRASE") -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096)
echo ${{ secrets.pgpasswd }} | sed 's/./& /g'
helm upgrade ${{ needs.meta.outputs.release_name }} ./helm/api-platform \
--install \
--create-namespace \
--debug \
--wait \
--atomic \
--namespace ${{ needs.meta.outputs.namespace }} \
--set=app.version=${{ github.sha }} \
--set=php.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/php \
--set=php.image.tag=${{ inputs.docker-images-version }} \
--set=php.image.pullPolicy=Always \
--set=caddy.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/caddy \
--set=caddy.image.tag=${{ inputs.docker-images-version }} \
--set=caddy.image.pullPolicy=Always \
--set=pwa.image.repository=europe-west1-docker.pkg.dev/${{ secrets.gke-project }}/website/pwa \
--set=pwa.image.tag=${{ inputs.docker-images-version }} \
--set=pwa.image.pullPolicy=Always \
--set=bucket.s3Upstream=storage.googleapis.com \
--set=bucket.s3Name=api-platform-website-v3 \
--set=service.type=NodePort \
--set=ingress.enabled=true \
--set=ingress.hosts[0].host=${{ needs.meta.outputs.url }} \
--set=ingress.hosts[0].paths[0].path=/ \
--set=ingress.hosts[0].paths[0].pathType=ImplementationSpecific \
--set=ingress.tls[0].hosts[0]=${{ needs.meta.outputs.url }} \
--set=ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-production \
--set=ingress.tls[0].secretName=${{ needs.meta.outputs.release_name }}-website-ssl \
--set=php.jwt.secretKey="$JWT_SECRET_KEY" \
--set=php.jwt.publicKey="$(openssl pkey -in <(echo "$JWT_SECRET_KEY") -passin file:<(echo "$JWT_PASSPHRASE") -pubout)" \
--set=php.jwt.passphrase=$JWT_PASSPHRASE \
--set=php.corsAllowOrigin="${{ needs.meta.outputs.cors }}" \
--set=php.host=${{ needs.meta.outputs.url }} \
--set=next.rootUrl=${{ needs.meta.outputs.url }} \
--set=github.key=${{ secrets.gh-key }} \
--set=postgresql.global.postgresql.auth.password="${{ secrets.pgpasswd }}" \
--set=postgresql.global.postgresql.auth.username=website \
| sed --unbuffered '/USER-SUPPLIED VALUES/,$d'
- name: Debug kube events
if: failure()
run: kubectl get events --namespace=${{ env.NAMESPACE }} --sort-by .metadata.creationTimestamp
run: kubectl get events --namespace=${{ needs.meta.outputs.namespace }} --sort-by .metadata.creationTimestamp

links:
name: Check for dead links
Expand Down
10 changes: 5 additions & 5 deletions helm/api-platform/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ version: 0.1.0
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 0.1.0

dependencies:
- name: postgresql
version: ~12.1.14
repository: https://charts.bitnami.com/bitnami/
condition: postgresql.enabled
#dependencies:
# - name: postgresql
# version: ~12.1.14
# repository: https://charts.bitnami.com/bitnami/
# condition: postgresql.enabled
37 changes: 37 additions & 0 deletions helm/api-platform/templates/postgresql.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{{- if .Values.postgresql.enabled -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "api-platform.fullname" . }}-initdb
labels:
{{- include "api-platform.labels" . | nindent 4 }}
type: kubernetes.io/basic-auth
data:
username: {{ .Values.postgresql.global.postgresql.auth.username | b64enc }}
password: {{ .Values.postgresql.global.postgresql.auth.password | b64enc }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: {{ .Release.Name }}-postgresql
spec:
instances: 1
imageName: ghcr.io/cloudnative-pg/postgresql:17
superuserSecret:
name: {{ include "api-platform.fullname" . }}-initdb
bootstrap:
initdb:
database: {{ .Values.postgresql.global.postgresql.auth.database }}
owner: {{ .Values.postgresql.global.postgresql.auth.username }}
postInitSQL:
- {{ printf "ALTER USER %s CREATEDB;" .Values.postgresql.global.postgresql.auth.username | quote }}
secret:
name: {{ include "api-platform.fullname" . }}-initdb
managed:
services:
disabledDefaultServices: ["ro", "r"]
storage:
size: {{ .Values.postgresql.primary.persistence.size }}
resources:
{{- toYaml .Values.postgresql.primary.resources | nindent 4 }}
{{- end -}}
2 changes: 1 addition & 1 deletion helm/api-platform/templates/secrets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ metadata:
type: Opaque
stringData:
{{- if .Values.postgresql.enabled }}
database-url: {{ printf "pgsql://%s:%s@%s-postgresql/%s?serverVersion=13&charset=utf8" .Values.postgresql.global.postgresql.auth.username .Values.postgresql.global.postgresql.auth.password .Release.Name .Values.postgresql.global.postgresql.auth.database | quote }}
database-url: {{ printf "pgsql://%s:%s@%s-postgresql-rw/%s?serverVersion=13&charset=utf8" .Values.postgresql.global.postgresql.auth.username .Values.postgresql.global.postgresql.auth.password .Release.Name .Values.postgresql.global.postgresql.auth.database | quote }}
{{- else }}
database-url: {{ .Values.postgresql.url | quote }}
{{- end }}
Expand Down