// Jenkinsfile for Rocky Man // // This repo holds only the deploy pipeline. The application source is pulled // from the upstream repository at build time (see SOURCE_REPO / SOURCE_REF), // so the code is not duplicated here. pipeline { agent { kubernetes { yaml """ apiVersion: v1 kind: Pod metadata: labels: jenkins: agent spec: containers: - name: docker image: docker:24-dind securityContext: privileged: true volumeMounts: - name: docker-sock mountPath: /var/run command: - dockerd-entrypoint.sh - name: docker-cli image: docker:24-cli command: - cat tty: true volumeMounts: - name: docker-sock mountPath: /var/run volumes: - name: docker-sock emptyDir: {} """ } } parameters { string( name: 'SOURCE_REPO', defaultValue: 'https://git.resf.org/documentation/rocky-man.git', description: 'Upstream application repository to build' ) string( name: 'SOURCE_REF', defaultValue: 'main', description: 'Branch or tag of the application to build' ) string( name: 'VERSIONS', defaultValue: '8.10 9.8 10.2', description: 'Rocky Linux versions to build (space-separated)' ) string( name: 'REPO_TYPES', defaultValue: 'BaseOS AppStream HighAvailability', description: 'Rocky Linux repos to build against (space-separated)' ) string( name: 'R2_BUCKET_NAME', defaultValue: 'rockyman', description: 'R2 bucket name for uploads' ) string( name: 'EXISTING_VERSIONS', defaultValue: '', description: 'Existing versions already built (space-separated)' ) string( name: 'PARALLEL_DOWNLOADS', defaultValue: '5', description: 'Number of parallel downloads' ) string( name: 'PARALLEL_CONVERSIONS', defaultValue: '10', description: 'Number of parallel conversions' ) } options { buildDiscarder(logRotator(numToKeepStr: '10')) timeout(time: 2, unit: 'HOURS') } stages { stage('Checkout Source') { steps { dir('rocky-man') { git url: "${params.SOURCE_REPO}", branch: "${params.SOURCE_REF}" } } } stage('Build Docker Image') { steps { container('docker-cli') { sh ''' until docker info > /dev/null 2>&1; do echo "Waiting for Docker daemon..." sleep 2 done docker build -t rocky-man:${BUILD_NUMBER} rocky-man docker tag rocky-man:${BUILD_NUMBER} rocky-man:latest ''' } } } stage('Build Man Pages') { steps { container('docker-cli') { sh ''' mkdir -p ./html ./tmp docker run --rm \ -v "$(pwd)/html:/data/html" \ -v "$(pwd)/tmp:/data/tmp" \ rocky-man:${BUILD_NUMBER} \ --versions ${VERSIONS} \ --repo-types ${REPO_TYPES} \ --parallel-downloads ${PARALLEL_DOWNLOADS} \ --parallel-conversions ${PARALLEL_CONVERSIONS} \ --existing-versions ${EXISTING_VERSIONS} ''' } } } stage('Upload to R2') { when { expression { return params.R2_BUCKET_NAME != "" } } steps { container('docker-cli') { withCredentials([ string(credentialsId: 'r2-account-id', variable: 'R2_ACCOUNT_ID'), string(credentialsId: 'r2-access-key-id', variable: 'AWS_ACCESS_KEY_ID'), string(credentialsId: 'r2-secret-access-key', variable: 'AWS_SECRET_ACCESS_KEY') ]) { // When EXISTING_VERSIONS is set this is a partial rebuild, // so omit --delete to preserve versions already in the bucket. sh ''' if [ -n "${EXISTING_VERSIONS}" ]; then DELETE_FLAG="" echo "Partial rebuild (EXISTING_VERSIONS set) -- preserving existing objects." else DELETE_FLAG="--delete" echo "Full rebuild -- bucket will be synced with --delete." fi docker run --rm \ -v "$(pwd)/html:/workspace/html" \ -e AWS_ACCESS_KEY_ID \ -e AWS_SECRET_ACCESS_KEY \ peakcom/s5cmd:latest \ --endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" \ sync ${DELETE_FLAG} /workspace/html/ "s3://${R2_BUCKET_NAME}/" ''' } } } } } post { success { echo 'Build completed and uploaded to R2!' } failure { echo 'Build failed!' } cleanup { container('docker-cli') { sh ''' docker rmi rocky-man:${BUILD_NUMBER} || true docker rmi rocky-man:latest || true ''' } } } }