pipeline { agent any options { timeout(time: 20, unit: 'MINUTES') timestamps() buildDiscarder(logRotator(numToKeepStr: '10')) disableConcurrentBuilds() } triggers { cron('H/30 * * * *') } environment { VENV_DIR = 'venv' PIP_CACHE_DIR = "${WORKSPACE}/.pip-cache" PYTHONUNBUFFERED = '1' } stages { stage('Checkout Code') { steps { checkout scm } } stage('Setup Python & Install Dependencies') { steps { sh ''' set -euxo pipefail python3 -m venv "${VENV_DIR}" "${VENV_DIR}/bin/python" -m pip install --upgrade pip wheel setuptools "${VENV_DIR}/bin/pip" install --cache-dir "${PIP_CACHE_DIR}" -U \ atproto \ playwright \ httpx \ arrow \ python-dotenv \ moviepy \ beautifulsoup4 \ charset-normalizer \ Pillow \ grapheme # Verify required imports "${VENV_DIR}/bin/python" -c "import moviepy; print('moviepy OK')" "${VENV_DIR}/bin/python" -c "import atproto; print('atproto OK')" "${VENV_DIR}/bin/python" -c "import playwright; print('playwright OK')" # Check FFmpeg ffmpeg -version # Install Playwright browser binaries "${VENV_DIR}/bin/python" -m playwright install chromium ''' } } stage('Run Script') { steps { withCredentials([ string(credentialsId: 'TIKTOK_JIJANTESFC_HANDLE', variable: 'TIKTOK_JIJANTESFC_HANDLE'), string(credentialsId: 'BSKY_JIJANTESFC_HANDLE', variable: 'BSKY_JIJANTESFC_HANDLE'), string(credentialsId: 'BSKY_JIJANTESFC_APP_PASSWORD', variable: 'BSKY_JIJANTESFC_APP_PASSWORD') ]) { sh ''' set -euxo pipefail "${VENV_DIR}/bin/python" tiktok2bsky.py \ --tiktok-handle "$TIKTOK_JIJANTESFC_HANDLE" \ --bsky-handle "$BSKY_JIJANTESFC_HANDLE" \ --bsky-password "$BSKY_JIJANTESFC_APP_PASSWORD" \ --bsky-base-url https://eurosky.social \ --bsky-langs es ''' } } } } post { always { archiveArtifacts artifacts: '*.log, *.json', allowEmptyArchive: true } } }