ci: added action
This commit is contained in:
parent
5c5ffb411b
commit
dbbaae7387
2 changed files with 191 additions and 0 deletions
66
.forgejo/workflows/README.md
Normal file
66
.forgejo/workflows/README.md
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
# Forgejo Actions for NextJS Slack Clone
|
||||||
|
|
||||||
|
This directory contains Forgejo action workflow configurations to build, push, and deploy our NextJS Slack Clone application using a secure service account approach.
|
||||||
|
|
||||||
|
## Workflows
|
||||||
|
|
||||||
|
### build-and-deploy.yaml
|
||||||
|
|
||||||
|
This workflow handles:
|
||||||
|
1. Building the Docker image
|
||||||
|
2. Pushing the image to the private registry (registrar.mattiaswiberg.com)
|
||||||
|
3. Deploying the application using Helm to the Kubernetes cluster with service account authentication
|
||||||
|
|
||||||
|
## Required Secrets
|
||||||
|
|
||||||
|
The following secrets need to be configured in your Forgejo repository settings:
|
||||||
|
|
||||||
|
1. `REGISTRY_USERNAME`: Username for the private Docker registry
|
||||||
|
2. `REGISTRY_PASSWORD`: Password for the private Docker registry
|
||||||
|
3. `K8S_SERVER_URL`: The Kubernetes API server URL (e.g., https://kubernetes.default.svc or your cluster endpoint)
|
||||||
|
4. `K8S_CA_CERT`: Base64-encoded certificate authority data for your Kubernetes cluster
|
||||||
|
5. `K8S_SA_TOKEN`: The service account token with permissions to deploy your application
|
||||||
|
6. `NEXT_PUBLIC_SUPABASE_URL`: Supabase URL for your project
|
||||||
|
7. `NEXT_PUBLIC_SUPABASE_ANON_KEY`: Supabase anonymous key for your project
|
||||||
|
|
||||||
|
## Setting Up Service Account Authentication
|
||||||
|
|
||||||
|
For secure Kubernetes authentication, we use a dedicated service account rather than a full kubeconfig. This follows security best practices by providing only the necessary permissions for CI/CD deployments.
|
||||||
|
|
||||||
|
To set up the required secrets:
|
||||||
|
|
||||||
|
1. Deploy the application once manually to create the service account and role
|
||||||
|
2. Get the service account token and cluster details:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get the service account token
|
||||||
|
SECRET_NAME=$(kubectl get serviceaccount nextjs-slack-clone -n default -o jsonpath='{.secrets[0].name}')
|
||||||
|
TOKEN=$(kubectl get secret $SECRET_NAME -n default -o jsonpath='{.data.token}' | base64 --decode)
|
||||||
|
echo $TOKEN # This is your K8S_SA_TOKEN
|
||||||
|
|
||||||
|
# Get the cluster CA certificate
|
||||||
|
CA_CERT=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
|
||||||
|
echo $CA_CERT # This is your K8S_CA_CERT
|
||||||
|
|
||||||
|
# Get the server URL
|
||||||
|
SERVER_URL=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.server}')
|
||||||
|
echo $SERVER_URL # This is your K8S_SERVER_URL
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Go to your repository settings
|
||||||
|
4. Navigate to "Actions" and then "Secrets"
|
||||||
|
5. Add each of the required secrets listed above
|
||||||
|
|
||||||
|
## Manual Trigger
|
||||||
|
|
||||||
|
You can also manually trigger the workflow using the "Actions" tab in your repository and selecting the "build-and-deploy" workflow.
|
||||||
|
|
||||||
|
## Monitoring Deployments
|
||||||
|
|
||||||
|
After deployment, you can check the status of your application using:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get pods -l app=nextjs-slack-clone
|
||||||
|
```
|
||||||
|
|
||||||
|
Or visit the application at https://chat.mattiaswiberg.com
|
||||||
125
.forgejo/workflows/build-and-deploy.yaml
Normal file
125
.forgejo/workflows/build-and-deploy.yaml
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
# Allow manual trigger
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: registrar.mattiaswiberg.com
|
||||||
|
IMAGE_NAME: nextjs-slack-clone
|
||||||
|
HELM_CHART_PATH: ./helm/nextjs-slack-clone
|
||||||
|
NAMESPACE: default # Change to your application's namespace
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: docker
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
run: |
|
||||||
|
# Set up buildx for multi-platform builds
|
||||||
|
docker buildx create --use
|
||||||
|
|
||||||
|
- name: Login to Container Registry
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin
|
||||||
|
|
||||||
|
# Generate a version tag based on commit hash
|
||||||
|
- name: Generate version tag
|
||||||
|
id: generate_tag
|
||||||
|
run: |
|
||||||
|
COMMIT_HASH=$(echo ${GITHUB_SHA} | cut -c1-7)
|
||||||
|
VERSION_TAG="${COMMIT_HASH}"
|
||||||
|
echo "VERSION_TAG=$VERSION_TAG" >> $GITHUB_OUTPUT
|
||||||
|
# Also set latest tag for convenience
|
||||||
|
echo "LATEST_TAG=latest" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
# Build and push Docker image
|
||||||
|
- name: Build and push
|
||||||
|
run: |
|
||||||
|
# Build the image
|
||||||
|
docker build \
|
||||||
|
--tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.generate_tag.outputs.VERSION_TAG }} \
|
||||||
|
--tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.generate_tag.outputs.LATEST_TAG }} \
|
||||||
|
--build-arg NEXT_PUBLIC_SUPABASE_URL=${{ secrets.NEXT_PUBLIC_SUPABASE_URL }} \
|
||||||
|
--build-arg NEXT_PUBLIC_SUPABASE_ANON_KEY=${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }} \
|
||||||
|
.
|
||||||
|
|
||||||
|
# Push the image with version tag and latest tag
|
||||||
|
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.generate_tag.outputs.VERSION_TAG }}
|
||||||
|
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.generate_tag.outputs.LATEST_TAG }}
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build-and-push
|
||||||
|
runs-on: docker
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Generate the same version tag as build-and-push job
|
||||||
|
- name: Generate version tag
|
||||||
|
id: generate_tag
|
||||||
|
run: |
|
||||||
|
COMMIT_HASH=$(echo ${GITHUB_SHA} | cut -c1-7)
|
||||||
|
VERSION_TAG="${COMMIT_HASH}"
|
||||||
|
echo "VERSION_TAG=$VERSION_TAG" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Set up kubectl
|
||||||
|
run: |
|
||||||
|
# Install kubectl
|
||||||
|
curl -LO "https://dl.k8s.io/release/stable.txt"
|
||||||
|
KUBE_VERSION=$(cat stable.txt)
|
||||||
|
curl -LO "https://dl.k8s.io/release/$KUBE_VERSION/bin/linux/amd64/kubectl"
|
||||||
|
chmod +x kubectl
|
||||||
|
mv kubectl /usr/local/bin/
|
||||||
|
|
||||||
|
- name: Set up Helm
|
||||||
|
run: |
|
||||||
|
# Install Helm
|
||||||
|
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||||
|
chmod +x get_helm.sh
|
||||||
|
./get_helm.sh
|
||||||
|
|
||||||
|
# Create kubeconfig using service account token
|
||||||
|
- name: Configure kubeconfig from service account
|
||||||
|
run: |
|
||||||
|
# Create kubeconfig using service account token
|
||||||
|
mkdir -p $HOME/.kube
|
||||||
|
cat > $HOME/.kube/config <<EOF
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Config
|
||||||
|
clusters:
|
||||||
|
- name: cluster
|
||||||
|
cluster:
|
||||||
|
server: ${{ secrets.K8S_SERVER_URL }}
|
||||||
|
certificate-authority-data: ${{ secrets.K8S_CA_CERT }}
|
||||||
|
users:
|
||||||
|
- name: ci-deployer
|
||||||
|
user:
|
||||||
|
token: ${{ secrets.K8S_SA_TOKEN }}
|
||||||
|
contexts:
|
||||||
|
- name: default
|
||||||
|
context:
|
||||||
|
cluster: cluster
|
||||||
|
user: ci-deployer
|
||||||
|
namespace: ${{ env.NAMESPACE }}
|
||||||
|
current-context: default
|
||||||
|
EOF
|
||||||
|
chmod 600 $HOME/.kube/config
|
||||||
|
|
||||||
|
- name: Deploy with Helm
|
||||||
|
run: |
|
||||||
|
# Deploy using Helm with service account authentication
|
||||||
|
helm upgrade --install nextjs-slack-clone ${{ env.HELM_CHART_PATH }} \
|
||||||
|
--namespace ${{ env.NAMESPACE }} \
|
||||||
|
--set image.tag=${{ steps.generate_tag.outputs.VERSION_TAG }} \
|
||||||
|
--set registry.username=${{ secrets.REGISTRY_USERNAME }} \
|
||||||
|
--set registry.password=${{ secrets.REGISTRY_PASSWORD }} \
|
||||||
|
--set env.NEXT_PUBLIC_SUPABASE_URL=${{ secrets.NEXT_PUBLIC_SUPABASE_URL }} \
|
||||||
|
--set env.NEXT_PUBLIC_SUPABASE_ANON_KEY=${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue