summaryrefslogtreecommitdiffci
path: root/Jenkinsfile
diff options
from:
to:
context:
space:
mode:
authorGravatar Saya Andy <saya.andy@posteo.com> 2026-07-30 10:59:45 +0700
committerGravatar Saya Andy <saya.andy@posteo.com> 2026-07-30 10:59:45 +0700
commitf73435c674c0ef67bde106d3f953ace17d22a856 (patch)
tree11c43abcfd67ca5223e61c954fe07a5d7b022d38 /Jenkinsfile
parent0d8fc1c94414f8e69cffe389620867a70ea85590 (diff)
parent4bdcac0a88d0510df9cdef2e99bee20370fe219b (diff)
downloadweb-main.tar.gz
web-main.zip
v0.17.3.2v0.17.3.2main
ci: use self-hosted sayag.it jenkins
Diffstat (limited to 'Jenkinsfile')
-rw-r--r--Jenkinsfile313
1 files changed, 313 insertions, 0 deletions
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..8633145
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,313 @@
+pipeline {
+ agent none
+
+ stages {
+ stage('Compile Tailwind CSS') {
+ agent {
+ docker {
+ image 'node:26.3.1-alpine3.24'
+ args '-v /tmp:/tmp -v /.npm:/.npm'
+ }
+ }
+ steps {
+ checkout scm
+ sh '''
+ npm install tailwindcss @tailwindcss/cli @tailwindcss/forms
+ npx tailwindcss -i static/input.css -o static/output.css --minify
+ '''
+ stash name: 'tailwindcss-output', includes: 'static/output.css'
+ }
+ }
+
+ stage('Matrix Build') {
+ matrix {
+ axes {
+ axis {
+ name 'GOOS'
+ values 'linux'
+ }
+ axis {
+ name 'GOARCH'
+ values 'arm64', 'amd64'
+ }
+ }
+ stages {
+ stage('Build') {
+ agent {
+ kubernetes {
+ defaultContainer 'kaniko'
+ yaml """
+apiVersion: v1
+kind: Pod
+metadata:
+ namespace: jenkins
+spec:
+ nodeSelector:
+ kubernetes.io/arch: ${GOARCH}
+ containers:
+ - name: kaniko
+ image: gcr.io/kaniko-project/executor:v1.24.0-debug
+ imagePullPolicy: Always
+ command: [ /busybox/cat ]
+ tty: true
+ resources:
+ requests:
+ cpu: "1"
+ memory: 2Gi
+ ephemeral-storage: 4Gi
+ limits:
+ memory: 4Gi
+ ephemeral-storage: 8Gi
+"""
+ }
+ }
+ environment {
+ IMAGE_PUSH_DESTINATION="registry.sayag.it/sayauz/web"
+ }
+ steps {
+ checkout scm
+ unstash 'tailwindcss-output'
+ container(name: 'kaniko', shell: '/busybox/sh') {
+ withCredentials([string(credentialsId: 'registry-sayagit-jenkins-password', variable: 'REGISTRY_SAYAGIT_JENKINS_PASSWORD')]) {
+ withEnv(['PATH+EXTRA=/busybox']) {
+ script {
+ env.GIT_COMMIT_SHORT = env.GIT_COMMIT ? env.GIT_COMMIT.take(7) : "unknown"
+ try {
+ sh '''#!/busybox/sh
+ mkdir -p /kaniko/.docker
+ printf '{"auths":{"registry.sayag.it":{"username":"jenkins","password":"%s"}}}' "$REGISTRY_SAYAGIT_JENKINS_PASSWORD" > /kaniko/.docker/config.json
+ /kaniko/executor --context `pwd` \
+ --custom-platform=linux/${GOARCH} \
+ --build-arg TARGETOS=linux \
+ --build-arg TARGETARCH=${GOARCH} \
+ --destination $IMAGE_PUSH_DESTINATION:commit-$GIT_COMMIT_SHORT-$GOARCH
+ '''
+ } catch (Exception e) {
+ echo "Caught exception: ${e.getMessage()}"
+ currentBuild.result = 'FAILURE'
+ throw e
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ stage('Stitch Manifest') {
+ agent {
+ kubernetes {
+ defaultContainer 'manifest-tool'
+ yaml """
+apiVersion: v1
+kind: Pod
+metadata:
+ namespace: jenkins
+spec:
+ containers:
+ - name: manifest-tool
+ image: mplatform/manifest-tool:alpine-v2.2.2
+ imagePullPolicy: Always
+ command: [ 'cat' ]
+ tty: true
+ resources:
+ requests:
+ cpu: "1"
+ memory: 2Gi
+ ephemeral-storage: 4Gi
+"""
+ }
+ }
+ environment {
+ IMAGE_PUSH_DESTINATION="registry.sayag.it/sayauz/web"
+ }
+ steps {
+ script {
+ env.GIT_COMMIT_SHORT = env.GIT_COMMIT ? env.GIT_COMMIT.take(7) : "unknown"
+ }
+ withCredentials([string(credentialsId: 'registry-sayagit-jenkins-password', variable: 'REGISTRY_SAYAGIT_JENKINS_PASSWORD')]) {
+ sh '''mkdir -p /root/.docker
+ printf '{"auths":{"registry.sayag.it":{"username":"jenkins","password":"%s"}}}' "$REGISTRY_SAYAGIT_JENKINS_PASSWORD" > /root/.docker/config.json
+
+ manifest-tool push from-args \
+ --platforms linux/amd64,linux/arm64 \
+ --template $IMAGE_PUSH_DESTINATION:commit-$GIT_COMMIT_SHORT-ARCH \
+ --target $IMAGE_PUSH_DESTINATION:commit-$GIT_COMMIT_SHORT
+ manifest-tool push from-args \
+ --platforms linux/amd64,linux/arm64 \
+ --template $IMAGE_PUSH_DESTINATION:commit-$GIT_COMMIT_SHORT-ARCH \
+ --target $IMAGE_PUSH_DESTINATION:latest
+ if [ "$TAG_NAME" != "" ]; then
+ manifest-tool push from-args \
+ --platforms linux/amd64,linux/arm64 \
+ --template $IMAGE_PUSH_DESTINATION:commit-$GIT_COMMIT_SHORT-ARCH \
+ --target $IMAGE_PUSH_DESTINATION:stable
+ manifest-tool push from-args \
+ --platforms linux/amd64,linux/arm64 \
+ --template $IMAGE_PUSH_DESTINATION:commit-$GIT_COMMIT_SHORT-ARCH \
+ --target $IMAGE_PUSH_DESTINATION:$TAG_NAME
+ fi
+ '''
+ }
+ }
+ }
+ stage('Deploy (Stage)') {
+ when { branch 'stage' }
+ agent {
+ kubernetes {
+ defaultContainer 'ansible'
+ yaml """
+apiVersion: v1
+kind: Pod
+metadata:
+ namespace: jenkins
+spec:
+ containers:
+ - name: ansible
+ image: ghcr.io/ansible/community-ansible-dev-tools:v26.7.2
+ command: [ 'cat' ]
+ tty: true
+ resources:
+ requests:
+ cpu: "500m"
+ memory: 1Gi
+"""
+ }
+ }
+ steps {
+ checkout scm
+ container('ansible') {
+ script {
+ env.GIT_COMMIT_SHORT = env.GIT_COMMIT ? env.GIT_COMMIT.take(7) : "unknown"
+
+ def secretVars = [
+ 'sayauz-web-stage-auth-salt' : 'AUTH_SALT',
+ 'sayauz-web-stage-s3-access-key-id' : 'S3_ACCESS_KEY_ID',
+ 'sayauz-web-stage-s3-secret-access-key' : 'S3_SECRET_ACCESS_KEY',
+ 'sayauz-web-stage-mail-salt' : 'MAIL_SALT',
+ 'sayauz-web-stage-mail-host' : 'MAIL_HOST',
+ 'sayauz-web-stage-mail-address' : 'MAIL_ADDRESS',
+ 'sayauz-web-stage-mail-username' : 'MAIL_USERNAME',
+ 'sayauz-web-stage-mail-password' : 'MAIL_PASSWORD'
+ ]
+ def bindings = secretVars.collect { id, varName -> string(credentialsId: id, variable: varName) }
+ bindings << sshUserPrivateKey(credentialsId: 'sayauz-svc-github', keyFileVariable: 'SSH_KEY_FILE', usernameVariable: 'SSH_USER')
+
+ withCredentials(bindings) {
+ sh '''
+ ansible-galaxy collection install community.docker
+
+ mkdir -p ~/.ssh
+ cp "$SSH_KEY_FILE" ~/.ssh/id_ed25519
+ chmod 600 ~/.ssh/id_ed25519
+ ssh-keyscan -H uz.saya.casa >> ~/.ssh/known_hosts
+
+ ssh -o ConnectTimeout=10 -i ~/.ssh/id_ed25519 "$SSH_USER@uz.saya.casa" "echo 'SSH connection successful'"
+
+ cd deploy
+ ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook \
+ playbook.yml \
+ -i inventory.yml \
+ -l stage \
+ --private-key ~/.ssh/id_ed25519 \
+ -u "$SSH_USER" \
+ -e saya_today_web_auth_salt="$AUTH_SALT" \
+ -e saya_today_web_s3_access_key_id="$S3_ACCESS_KEY_ID" \
+ -e saya_today_web_s3_secret_access_key="$S3_SECRET_ACCESS_KEY" \
+ -e saya_today_web_environment=stage \
+ -e saya_today_web_tag=commit-$GIT_COMMIT_SHORT \
+ -e saya_today_web_mail_salt="$MAIL_SALT" \
+ -e saya_today_web_mail_host="$MAIL_HOST" \
+ -e saya_today_web_mail_address="$MAIL_ADDRESS" \
+ -e saya_today_web_mail_username="$MAIL_USERNAME" \
+ -e saya_today_web_mail_password="$MAIL_PASSWORD"
+ '''
+ }
+ }
+ }
+ }
+ }
+ stage('Deploy (Prod)') {
+ when { buildingTag() }
+ agent {
+ kubernetes {
+ defaultContainer 'ansible'
+ yaml """
+apiVersion: v1
+kind: Pod
+metadata:
+ namespace: jenkins
+spec:
+ containers:
+ - name: ansible
+ image: ghcr.io/ansible/community-ansible-dev-tools:v26.7.2
+ command: [ 'cat' ]
+ tty: true
+ resources:
+ requests:
+ cpu: "500m"
+ memory: 1Gi
+"""
+ }
+ }
+ steps {
+ checkout scm
+ container('ansible') {
+ script {
+ def secretVars = [
+ 'sayauz-web-prod-auth-salt' : 'AUTH_SALT',
+ 'sayauz-web-prod-s3-access-key-id' : 'S3_ACCESS_KEY_ID',
+ 'sayauz-web-prod-s3-secret-access-key' : 'S3_SECRET_ACCESS_KEY',
+ 'sayauz-web-prod-mail-salt' : 'MAIL_SALT',
+ 'sayauz-web-prod-mail-host' : 'MAIL_HOST',
+ 'sayauz-web-prod-mail-address' : 'MAIL_ADDRESS',
+ 'sayauz-web-prod-mail-username' : 'MAIL_USERNAME',
+ 'sayauz-web-prod-mail-password' : 'MAIL_PASSWORD',
+ 'sayauz-web-prod-verification-google' : 'GOOGLE_VERIFICATION',
+ 'sayauz-web-prod-verification-yandex' : 'YANDEX_VERIFICATION',
+ 'sayauz-web-prod-verification-bing' : 'BING_VERIFICATION'
+ ]
+ def bindings = secretVars.collect { id, varName -> string(credentialsId: id, variable: varName) }
+ bindings << sshUserPrivateKey(credentialsId: 'sayauz-svc-github', keyFileVariable: 'SSH_KEY_FILE', usernameVariable: 'SSH_USER')
+
+ withCredentials(bindings) {
+ sh '''
+ ansible-galaxy collection install community.docker
+
+ mkdir -p ~/.ssh
+ cp "$SSH_KEY_FILE" ~/.ssh/id_ed25519
+ chmod 600 ~/.ssh/id_ed25519
+ ssh-keyscan -H uz.saya.casa >> ~/.ssh/known_hosts
+
+ ssh -o ConnectTimeout=10 -i ~/.ssh/id_ed25519 "$SSH_USER@uz.saya.casa" "echo 'SSH connection successful'"
+
+ cd deploy
+ ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook \
+ playbook.yml \
+ -i inventory.yml \
+ -l prod \
+ --private-key ~/.ssh/id_ed25519 \
+ -u "$SSH_USER" \
+ -e saya_today_web_auth_salt="$AUTH_SALT" \
+ -e saya_today_web_s3_access_key_id="$S3_ACCESS_KEY_ID" \
+ -e saya_today_web_s3_secret_access_key="$S3_SECRET_ACCESS_KEY" \
+ -e saya_today_web_environment=prod \
+ -e saya_today_web_tag=$TAG_NAME \
+ -e saya_today_web_mail_salt="$MAIL_SALT" \
+ -e saya_today_web_mail_host="$MAIL_HOST" \
+ -e saya_today_web_mail_address="$MAIL_ADDRESS" \
+ -e saya_today_web_mail_username="$MAIL_USERNAME" \
+ -e saya_today_web_mail_password="$MAIL_PASSWORD" \
+ -e saya_today_google_verification="$GOOGLE_VERIFICATION" \
+ -e saya_today_yandex_verification="$YANDEX_VERIFICATION" \
+ -e saya_today_bing_verification="$BING_VERIFICATION"
+ '''
+ }
+ }
+ }
+ }
+ }
+ }
+}