Jenkinsfile 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. // Helper function for database operations
  2. def executeDbQuery(String query, String description = null) {
  3. echo "SQL query: ${query} ### ${description}"
  4. sh """mysql -u ${DEPLOY_DB_USER} --password=${DEPLOY_DB_PWD} -D ${DEPLOY_DB_NAME} -h ${DEPLOY_DB_HOST} -e "${query}" """
  5. }
  6. // Helper function for database operations
  7. def executeDbMultiQuery(String queries, String description = null) {
  8. echo "SQL query: ${queries} ### ${description}"
  9. sh """mysql -u ${DEPLOY_DB_USER} --password=${DEPLOY_DB_PWD} -D ${DEPLOY_DB_NAME} -h ${DEPLOY_DB_HOST} << 'EOF'
  10. ${queries}
  11. EOF"""
  12. }
  13. pipeline {
  14. agent any
  15. options {
  16. buildDiscarder(logRotator(numToKeepStr: '10'))
  17. timeout(time: 60, unit: 'MINUTES')
  18. timestamps()
  19. }
  20. environment {
  21. // Node.js configuration
  22. PATH = "/var/lib/jenkins/.nvm/versions/node/v20.19.3/bin:$PATH"
  23. // Binary paths
  24. PHP = "/usr/bin/php8.3"
  25. GIT = "git"
  26. CURL = "curl"
  27. PHING = "/usr/bin/phing-3.1.0.phar"
  28. DOXYGEN = "/usr/bin/doxygen"
  29. COMPOSER_PHAR = "/usr/bin/composer.phar"
  30. // Modules to install
  31. MODULES = "bx_posts,bx_timeline,bx_contact,bx_developer,bx_antispam,bx_convos,bx_organizations,bx_notifications,bx_ocean,bx_ether,bx_accounts,bx_albums,bx_facebook,bx_tricon,bx_oauth,bx_chat_plus,bx_datafox,bx_payment,bx_market,bx_groups,bx_intercom,bx_googlecon,bx_linkedin,bx_twitter,bx_mailchimp,bx_forum,bx_acl,bx_events,bx_files,bx_glossary,bx_googletagman,bx_photos,bx_polls,bx_profiler,bx_quoteofday,bx_smtp,bx_shopify,bx_snipcart,bx_se_migration,bx_spaces,bx_stripe_connect,bx_unacon,bx_videos,bx_charts,bx_dolcon,bx_fontawesome,bx_channels,bx_attendant,bx_massmailer,bx_directory,bx_plyr,bx_ads,bx_decorous,bx_lucid,bx_credits,bx_wiki,bx_tasks,bx_courses,bx_classes,bx_artificer,bx_donations,bx_feedback,bx_help_tours,bx_stream,bx_attendant,bx_messenger,bx_analytics,bx_reputation,bx_ru"
  32. // Test install parameters
  33. INSTALL_DB_NAME = "mainsite_virtual"
  34. INSTALL_DB_USER = "mainsite_una"
  35. INSTALL_DB_PWD = "*****"
  36. // Package parameters
  37. PACKAGE_PUBLISH_DIR = "/var/www/vhosts/mainsite/html/builds"
  38. PACKAGE_PUBLISH_LATEST_FILE = "${PACKAGE_PUBLISH_DIR}/latest-file.txt"
  39. PACKAGE_PUBLISH_LATEST_DATE = "${PACKAGE_PUBLISH_DIR}/latest-date.txt"
  40. PACKAGE_PUBLISH_LATEST_BUILD = "${PACKAGE_PUBLISH_DIR}/latest-build.txt"
  41. // Deploy parameters
  42. DEPLOY_PATH = "/var/www/vhosts/mainsite/html/test"
  43. DEPLOY_HTTP_HOST = "ci.una.io"
  44. DEPLOY_HTTP_PATH = "/test/"
  45. DEPLOY_DOC_ROOT = "/var/www/vhosts/mainsite/html"
  46. DEPLOY_DB_HOST = "127.0.0.1"
  47. DEPLOY_DB_NAME = "mainsite_una"
  48. DEPLOY_DB_USER = "mainsite_una"
  49. DEPLOY_DB_PWD = "*****"
  50. // Documentation parameters
  51. DOCS_OUTPUT = "/var/www/vhosts/mainsite/html/docs"
  52. // Environment flags
  53. UNA_HTTPS = "1"
  54. // Date stamp for package
  55. DSTAMP = sh(script: 'date +"%Y%m%d"', returnStdout: true).trim()
  56. ZIPFILE = "UNA-${DSTAMP}-${BUILD_NUMBER}.zip"
  57. // Demo users
  58. DEMO_USERS_PASS = "*****"
  59. DEMO_USERS_SALT = "*****"
  60. DEMO_S3_BUCKET = "una-ci"
  61. DEMO_S3_ENDPOINT = "us-east-1.linodeobjects.com"
  62. DEMO_S3_KEY = "*****"
  63. DEMO_S3_SECRET = "*****"
  64. DEMO_GOOGLE_MAPS_API_KEY = "*****"
  65. DEMO_MESSENGER_URL = "https://una.io:5443"
  66. DEMO_API_OAUTH_ID = "*****"
  67. DEMO_API_OAUTH_SECRET = "*****"
  68. DEMO_API_KEY = "*****"
  69. DEMO_SOCKETS_URL = "https://ci.una.io"
  70. DEMO_SOCKETS_APP_ID = "neo-ci"
  71. DEMO_SOCKETS_KEY = "neo-ci"
  72. DEMO_SOCKETS_SECRET = "*****"
  73. TEST_USER_ADMIN_PWD = "*****"
  74. TEST_USER_REGULAR_PWD = "*****"
  75. TEST_USER_TOM_PWD = "*****"
  76. }
  77. stages {
  78. stage('Prepare & worspace clean up') {
  79. steps {
  80. script {
  81. echo "Cleaning workspace before proceeding"
  82. // Clean up workspace
  83. cleanWs(
  84. cleanWhenAborted: true,
  85. cleanWhenFailure: true,
  86. cleanWhenNotBuilt: true,
  87. cleanWhenSuccess: true,
  88. cleanWhenUnstable: true,
  89. deleteDirs: true,
  90. disableDeferredWipeout: true
  91. )
  92. echo "NodeJS version:"
  93. sh 'node -v'
  94. echo "Starting UNA CI/CD Pipeline"
  95. echo "Build Number: ${BUILD_NUMBER}"
  96. echo "Package File: ${ZIPFILE}"
  97. }
  98. }
  99. }
  100. stage('Clone UNA repository') {
  101. steps {
  102. git branch: 'master',
  103. url: 'https://github.com/unacms/UNA/',
  104. credentialsId: '0043feeb-9df7-4494-9b2b-d6c8a1b8ca08'
  105. }
  106. }
  107. stage('Clone additional UNA modules') {
  108. parallel {
  109. stage('Clone: Media Manager') {
  110. steps {
  111. dir('modules/boonex/media') {
  112. git branch: 'master',
  113. url: 'git@github.com:unacms/media-manager.git',
  114. credentialsId: '0043feeb-9df7-4494-9b2b-d6c8a1b8ca08'
  115. }
  116. }
  117. }
  118. stage('Clone: Messenger') {
  119. steps {
  120. dir('modules/boonex/messenger') {
  121. git branch: 'master',
  122. url: 'git@github.com:unacms/jot-client-una.git',
  123. credentialsId: '0043feeb-9df7-4494-9b2b-d6c8a1b8ca08'
  124. }
  125. }
  126. }
  127. }
  128. }
  129. stage('Build messenger') {
  130. steps {
  131. script {
  132. dir('modules/boonex/messenger') {
  133. echo "Building messenger"
  134. sh 'yarn && yarn build'
  135. }
  136. }
  137. }
  138. }
  139. stage('Install dependencies') {
  140. steps {
  141. script {
  142. echo "Cleaning some files"
  143. sh '${PHP} ${PHING} clean_install'
  144. echo "Install PHP and JS dependences"
  145. sh '${PHP} ${PHING} -verbose -Dphp=${PHP} -Dcomposer=${COMPOSER_PHAR} prepare'
  146. }
  147. }
  148. }
  149. stage('Test installation') {
  150. steps {
  151. script {
  152. echo "Setting up permissions"
  153. sh '${PHP} ${PHING} change_permissions'
  154. echo "Performing installation for testing"
  155. sh '''
  156. ${PHP} ${PHING} -verbose -debug \
  157. -Dphp=${PHP} \
  158. -Ddb_name=${INSTALL_DB_NAME} \
  159. -Ddb_user=${INSTALL_DB_USER} \
  160. -Ddb_password=${INSTALL_DB_PWD} \
  161. -Dmodules="${MODULES}" \
  162. install
  163. '''
  164. }
  165. }
  166. }
  167. stage('Unit tests') {
  168. steps {
  169. script {
  170. echo "Running PHP Unit Tests"
  171. def status = sh(
  172. script: "${PHP} tests/vendor/bin/phpunit -c tests/phpunit.xml",
  173. returnStatus: true
  174. )
  175. echo "PHPUnit exit code: ${status}"
  176. }
  177. }
  178. post {
  179. always {
  180. // Publish test results if they exist
  181. archiveArtifacts artifacts: 'logs/junit.xml', allowEmptyArchive: true
  182. junit checksName: 'Unit-Tests', testResults: 'logs/junit.xml'
  183. }
  184. }
  185. }
  186. stage('Code Quality Analysis') {
  187. steps {
  188. script {
  189. echo "Running PHP Copy Paste Detector"
  190. sh '''
  191. ${PHP} -d memory_limit=512M /usr/bin/phpcpd.phar --min-lines 18 --log-pmd logs/phpcpd.xml \
  192. --exclude plugins \
  193. --exclude plugins_public \
  194. --exclude modules/boonex/xero/plugins \
  195. --exclude upgrade \
  196. --exclude cache \
  197. --exclude cache_public \
  198. --exclude storage \
  199. --exclude logs \
  200. --exclude tmp \
  201. --exclude samples \
  202. --exclude tests \
  203. --exclude modules/boonex/lucid/data \
  204. --exclude modules/boonex/decorous/data \
  205. --exclude modules/boonex/protean/data \
  206. --exclude modules/boonex/artificer/data \
  207. --exclude modules/boonex/membership_pricing \
  208. --exclude modules/boonex/se_migration \
  209. --exclude modules/boonex/dolphin_migration \
  210. --exclude modules/boonex/anon_follow \
  211. --exclude modules/boonex/plyr/updates \
  212. --exclude modules/boonex/classes/updates \
  213. --exclude modules/boonex/nexus/updates \
  214. --exclude modules/boonex/dolphin_migration/updates \
  215. --exclude modules/boonex/accounts/updates \
  216. --exclude modules/boonex/invites/updates \
  217. --exclude modules/boonex/files/updates \
  218. --exclude modules/boonex/intercom/updates \
  219. --exclude modules/boonex/oauth2/updates \
  220. --exclude modules/boonex/linkedin_connect/updates \
  221. --exclude modules/boonex/videos/updates \
  222. --exclude modules/boonex/market/updates \
  223. --exclude modules/boonex/russian/updates \
  224. --exclude modules/boonex/decorous/updates \
  225. --exclude modules/boonex/groups/updates \
  226. --exclude modules/boonex/lucid/updates \
  227. --exclude modules/boonex/api/updates \
  228. --exclude modules/boonex/fontawesome/updates \
  229. --exclude modules/boonex/spaces/updates \
  230. --exclude modules/boonex/elasticsearch/updates \
  231. --exclude modules/boonex/google_connect/updates \
  232. --exclude modules/boonex/froala/updates \
  233. --exclude modules/boonex/twitter_connect/updates \
  234. --exclude modules/boonex/payment/updates \
  235. --exclude modules/boonex/artificer/updates \
  236. --exclude modules/boonex/events/updates \
  237. --exclude modules/boonex/messenger/updates \
  238. --exclude modules/boonex/donations/updates \
  239. --exclude modules/boonex/google_tagmanager/updates \
  240. --exclude modules/boonex/contact/updates \
  241. --exclude modules/boonex/polls/updates \
  242. --exclude modules/boonex/developer/updates \
  243. --exclude modules/boonex/mailchimp/updates \
  244. --exclude modules/boonex/snipcart/updates \
  245. --exclude modules/boonex/chat_plus/updates \
  246. --exclude modules/boonex/persons/updates \
  247. --exclude modules/boonex/glossary/updates \
  248. --exclude modules/boonex/xero/updates \
  249. --exclude modules/boonex/charts/updates \
  250. --exclude modules/boonex/credits/updates \
  251. --exclude modules/boonex/acl/updates \
  252. --exclude modules/boonex/massmailer/updates \
  253. --exclude modules/boonex/ocean/updates \
  254. --exclude modules/boonex/markerio/updates \
  255. --exclude modules/boonex/english/updates \
  256. --exclude modules/boonex/profiler/updates \
  257. --exclude modules/boonex/shopify/updates \
  258. --exclude modules/boonex/timeline/updates \
  259. --exclude modules/boonex/forum/updates \
  260. --exclude modules/boonex/smtpmailer/updates \
  261. --exclude modules/boonex/albums/updates \
  262. --exclude modules/boonex/antispam/updates \
  263. --exclude modules/boonex/photos/updates \
  264. --exclude modules/boonex/courses/updates \
  265. --exclude modules/boonex/ads/updates \
  266. --exclude modules/boonex/posts/updates \
  267. --exclude modules/boonex/protean/updates \
  268. --exclude modules/boonex/wiki/updates \
  269. --exclude modules/boonex/facebook_connect/updates \
  270. --exclude modules/boonex/convos/updates \
  271. --exclude modules/boonex/dolphin_connect/updates \
  272. --exclude modules/boonex/tasks/updates \
  273. --exclude modules/boonex/help_tours/updates \
  274. --exclude modules/boonex/stripe_connect/updates \
  275. --exclude modules/boonex/stream/updates \
  276. --exclude modules/boonex/datafox/updates \
  277. --exclude modules/boonex/notifications/updates \
  278. --exclude modules/boonex/attendant/updates \
  279. --exclude modules/boonex/channels/updates \
  280. --exclude modules/boonex/analytics/updates \
  281. --exclude modules/boonex/una_connect/updates \
  282. --exclude modules/boonex/quoteofday/updates \
  283. --exclude modules/boonex/organizations/updates \
  284. --exclude modules/boonex/plyr/install/config.php \
  285. --exclude modules/boonex/classes/install/config.php \
  286. --exclude modules/boonex/nexus/install/config.php \
  287. --exclude modules/boonex/dolphin_migration/install/config.php \
  288. --exclude modules/boonex/accounts/install/config.php \
  289. --exclude modules/boonex/invites/install/config.php \
  290. --exclude modules/boonex/files/install/config.php \
  291. --exclude modules/boonex/intercom/install/config.php \
  292. --exclude modules/boonex/oauth2/install/config.php \
  293. --exclude modules/boonex/linkedin_connect/install/config.php \
  294. --exclude modules/boonex/videos/install/config.php \
  295. --exclude modules/boonex/market/install/config.php \
  296. --exclude modules/boonex/russian/install/config.php \
  297. --exclude modules/boonex/decorous/install/config.php \
  298. --exclude modules/boonex/groups/install/config.php \
  299. --exclude modules/boonex/lucid/install/config.php \
  300. --exclude modules/boonex/api/install/config.php \
  301. --exclude modules/boonex/fontawesome/install/config.php \
  302. --exclude modules/boonex/spaces/install/config.php \
  303. --exclude modules/boonex/elasticsearch/install/config.php \
  304. --exclude modules/boonex/google_connect/install/config.php \
  305. --exclude modules/boonex/froala/install/config.php \
  306. --exclude modules/boonex/twitter_connect/install/config.php \
  307. --exclude modules/boonex/payment/install/config.php \
  308. --exclude modules/boonex/artificer/install/config.php \
  309. --exclude modules/boonex/events/install/config.php \
  310. --exclude modules/boonex/messenger/install/config.php \
  311. --exclude modules/boonex/donations/install/config.php \
  312. --exclude modules/boonex/google_tagmanager/install/config.php \
  313. --exclude modules/boonex/contact/install/config.php \
  314. --exclude modules/boonex/polls/install/config.php \
  315. --exclude modules/boonex/developer/install/config.php \
  316. --exclude modules/boonex/mailchimp/install/config.php \
  317. --exclude modules/boonex/snipcart/install/config.php \
  318. --exclude modules/boonex/chat_plus/install/config.php \
  319. --exclude modules/boonex/persons/install/config.php \
  320. --exclude modules/boonex/glossary/install/config.php \
  321. --exclude modules/boonex/xero/install/config.php \
  322. --exclude modules/boonex/charts/install/config.php \
  323. --exclude modules/boonex/credits/install/config.php \
  324. --exclude modules/boonex/acl/install/config.php \
  325. --exclude modules/boonex/massmailer/install/config.php \
  326. --exclude modules/boonex/ocean/install/config.php \
  327. --exclude modules/boonex/markerio/install/config.php \
  328. --exclude modules/boonex/english/install/config.php \
  329. --exclude modules/boonex/profiler/install/config.php \
  330. --exclude modules/boonex/shopify/install/config.php \
  331. --exclude modules/boonex/timeline/install/config.php \
  332. --exclude modules/boonex/forum/install/config.php \
  333. --exclude modules/boonex/smtpmailer/install/config.php \
  334. --exclude modules/boonex/albums/install/config.php \
  335. --exclude modules/boonex/antispam/install/config.php \
  336. --exclude modules/boonex/photos/install/config.php \
  337. --exclude modules/boonex/courses/install/config.php \
  338. --exclude modules/boonex/ads/install/config.php \
  339. --exclude modules/boonex/posts/install/config.php \
  340. --exclude modules/boonex/protean/install/config.php \
  341. --exclude modules/boonex/wiki/install/config.php \
  342. --exclude modules/boonex/facebook_connect/install/config.php \
  343. --exclude modules/boonex/convos/install/config.php \
  344. --exclude modules/boonex/dolphin_connect/install/config.php \
  345. --exclude modules/boonex/tasks/install/config.php \
  346. --exclude modules/boonex/help_tours/install/config.php \
  347. --exclude modules/boonex/stripe_connect/install/config.php \
  348. --exclude modules/boonex/stream/install/config.php \
  349. --exclude modules/boonex/datafox/install/config.php \
  350. --exclude modules/boonex/notifications/install/config.php \
  351. --exclude modules/boonex/attendant/install/config.php \
  352. --exclude modules/boonex/channels/install/config.php \
  353. --exclude modules/boonex/analytics/install/config.php \
  354. --exclude modules/boonex/una_connect/install/config.php \
  355. --exclude modules/boonex/quoteofday/install/config.php \
  356. --exclude modules/boonex/organizations/install/config.php \
  357. . || true
  358. '''
  359. echo "Checking log files:"
  360. sh 'ls -la logs/'
  361. }
  362. }
  363. post {
  364. always {
  365. // Archive code quality reports
  366. // archiveArtifacts artifacts: 'logs/phpcpd.xml', allowEmptyArchive: true, followSymlinks: false
  367. recordIssues(
  368. sourceCodeRetention: 'LAST_BUILD',
  369. tools: [cpd(pattern: 'logs/phpcpd.xml')]
  370. )
  371. }
  372. }
  373. }
  374. stage('Package Build') {
  375. steps {
  376. script {
  377. echo "Creating package: ${ZIPFILE}"
  378. sh '${PHP} ${PHING} -Dpackage_file=${ZIPFILE} package'
  379. sh 'cp "packages/${ZIPFILE}" ${PACKAGE_PUBLISH_DIR}'
  380. // Update latest build info
  381. sh 'echo ${ZIPFILE} > ${PACKAGE_PUBLISH_LATEST_FILE}'
  382. sh 'date +"%Y.%m.%d" > ${PACKAGE_PUBLISH_LATEST_DATE}'
  383. sh 'echo ${BUILD_NUMBER} > ${PACKAGE_PUBLISH_LATEST_BUILD}'
  384. }
  385. }
  386. post {
  387. success {
  388. archiveArtifacts artifacts: "packages/${ZIPFILE}", fingerprint: true
  389. }
  390. }
  391. }
  392. stage('Deployment') {
  393. steps {
  394. script {
  395. echo "Cleaning up test site"
  396. sh '"${DEPLOY_PATH}/../../cleanup_test_site.sh"'
  397. echo "Deploying to test environment"
  398. sh '''
  399. ${PHP} ${PHING} \
  400. -Dphp=${PHP} \
  401. -Ddeploy_path=${DEPLOY_PATH} \
  402. -Dhttp_host=${DEPLOY_HTTP_HOST} \
  403. -Dhttp_path=${DEPLOY_HTTP_PATH} \
  404. -Ddoc_root=${DEPLOY_DOC_ROOT} \
  405. -Ddb_name=${DEPLOY_DB_NAME} \
  406. -Ddb_host=${DEPLOY_DB_HOST} \
  407. -Ddb_user=${DEPLOY_DB_USER} \
  408. -Ddb_password=${DEPLOY_DB_PWD} \
  409. -Dmodules="${MODULES}" \
  410. deploy
  411. '''
  412. }
  413. }
  414. }
  415. stage('Database Configuration') {
  416. steps {
  417. script {
  418. echo "Configuring database for UI tests"
  419. // Maps API key
  420. executeDbQuery(
  421. "UPDATE sys_options SET value = '${DEMO_GOOGLE_MAPS_API_KEY}' WHERE name = 'sys_maps_api_key'",
  422. "Setting Google Maps API key"
  423. )
  424. // Messenger server
  425. executeDbQuery(
  426. "UPDATE sys_options SET value = '${DEMO_MESSENGER_URL}' WHERE name = 'bx_messenger_server_url'",
  427. "Configuring messenger server URL"
  428. )
  429. // Create test users
  430. echo "Creating test users"
  431. def users = ['user', 'lily', 'eva', 'linda', 'emma', 'karen', 'ella', 'viky', 'mila', 'eric', 'luck', 'jack', 'rob', 'dave', 'tom', 'andy', 'ivan']
  432. users.each { user ->
  433. executeDbMultiQuery("""
  434. SET sql_mode = '';
  435. INSERT INTO sys_accounts (name, email, email_confirmed, receive_updates, receive_news, password, salt, role, added) VALUES
  436. ('${user}', '${user}@example.com', 1, 0, 0, SHA1(CONCAT(MD5('${DEMO_USERS_PASS}'), '${DEMO_USERS_SALT}')), '${DEMO_USERS_SALT}', 1, UNIX_TIMESTAMP());
  437. SET @iAccountId = LAST_INSERT_ID();
  438. INSERT INTO sys_profiles (account_id, type, content_id, status) VALUES
  439. (@iAccountId, 'system', @iAccountId, 'active');
  440. """, "Creating user: ${user}")
  441. }
  442. // Storage configuration
  443. echo "Configuring S3 storage"
  444. executeDbQuery(
  445. "UPDATE sys_options SET value = '${DEMO_S3_KEY}' WHERE name = 'sys_storage_s3_access_key'",
  446. "Setting S3 access key"
  447. )
  448. executeDbQuery(
  449. "UPDATE sys_options SET value = '${DEMO_S3_SECRET}' WHERE name = 'sys_storage_s3_secret_key'",
  450. "Setting S3 secret key"
  451. )
  452. executeDbQuery(
  453. "UPDATE sys_options SET value = '${DEMO_S3_BUCKET}' WHERE name = 'sys_storage_s3_bucket'",
  454. "Setting S3 bucket name"
  455. )
  456. executeDbQuery(
  457. "UPDATE sys_options SET value = '${DEMO_S3_ENDPOINT}' WHERE name = 'sys_storage_s3_endpoint'",
  458. "Setting S3 endpoint"
  459. )
  460. executeDbQuery(
  461. "UPDATE sys_objects_storage SET engine = 'S3'",
  462. "Switching storage engine to S3"
  463. )
  464. // SEO URI rewrites
  465. executeDbQuery(
  466. "INSERT INTO sys_seo_uri_rewrites SET uri_orig = 'view-persons-profile', uri_rewrite = 'u'",
  467. "Adding person profile URL rewrite"
  468. )
  469. executeDbQuery(
  470. "INSERT INTO sys_seo_uri_rewrites SET uri_orig = 'view-organization-profile', uri_rewrite = 'o'",
  471. "Adding organization profile URL rewrite"
  472. )
  473. // Enable subgroups
  474. executeDbQuery(
  475. "UPDATE sys_objects_privacy SET spaces = 'bx_events,bx_spaces,bx_groups' WHERE object = 'bx_groups_allow_view_to'",
  476. "Enabling subgroups functionality"
  477. )
  478. }
  479. }
  480. }
  481. stage('API Configuration') {
  482. parallel {
  483. stage('Old API Setup') {
  484. steps {
  485. script {
  486. echo "Configuring old OAuth API"
  487. executeDbMultiQuery("""
  488. INSERT INTO bx_oauth_clients (title, client_id, client_secret, redirect_uri, grant_types, scope, parent_id, user_id) VALUES
  489. ('nextjs', '${DEMO_API_OAUTH_ID}', '${DEMO_API_OAUTH_SECRET}', 'http://app.una.io:3000/', NULL, 'service', 0, 1);
  490. SET @iClientId = LAST_INSERT_ID();
  491. INSERT INTO bx_oauth_allowed_origins (client_id, url) VALUES
  492. (@iClientId, 'https://ci.una.io:3000');
  493. """, "Setting up OAuth client and allowed origins")
  494. }
  495. }
  496. }
  497. stage('New API Setup') {
  498. steps {
  499. script {
  500. echo "Configuring new API system"
  501. executeDbMultiQuery("""
  502. INSERT INTO sys_api_keys (title, `key`, `order`) VALUES
  503. ('NextJS', '${DEMO_API_KEY}', 1);
  504. INSERT INTO sys_api_origins (url, `order`) VALUES
  505. ('neo://app', 1),
  506. ('http://localhost:3000', 2),
  507. ('https://neo.vercel.app/', 4),
  508. ('https://neo.so/', 5),
  509. ('http://hihi.com', 6),
  510. ('https://hihi.com', 7),
  511. ('https://neo-ci.una.io', 8);
  512. UPDATE sys_options SET value = 'on' WHERE name = 'sys_api_enable';
  513. UPDATE sys_options SET value = 'on' WHERE name = 'sys_api_access_by_origin';
  514. UPDATE sys_options SET value = 'on' WHERE name = 'sys_api_access_by_key';
  515. UPDATE sys_options SET value = 'on' WHERE name = 'sys_session_auth';
  516. """, "Setting up new API keys, origins and enabling API features")
  517. }
  518. }
  519. }
  520. stage('Sockets Server Setup') {
  521. steps {
  522. script {
  523. echo "Configuring sockets server"
  524. executeDbMultiQuery("""
  525. UPDATE sys_options SET value = 'sys_sockets_soketi' WHERE name = 'sys_sockets_type';
  526. UPDATE sys_options SET value = '${DEMO_SOCKETS_URL}' WHERE name = 'sys_sockets_url';
  527. UPDATE sys_options SET value = '${DEMO_SOCKETS_APP_ID}' WHERE name = 'sys_sockets_app_id';
  528. UPDATE sys_options SET value = '${DEMO_SOCKETS_KEY}' WHERE name = 'sys_sockets_key';
  529. UPDATE sys_options SET value = '${DEMO_SOCKETS_SECRET}' WHERE name = 'sys_sockets_secret';
  530. """, "Configuring Soketi sockets server settings")
  531. }
  532. }
  533. }
  534. }
  535. }
  536. stage('UI Tests') {
  537. steps {
  538. timeout(time: 6, unit: 'MINUTES') {
  539. script {
  540. echo "Creating cache directories"
  541. sh '''
  542. mkdir -p -m 0777 "${DEPLOY_PATH}/cache/CSS"
  543. mkdir -p -m 0777 "${DEPLOY_PATH}/cache/HTML"
  544. mkdir -p -m 0777 "${DEPLOY_PATH}/cache/URI"
  545. '''
  546. dir('una-ui-test3') {
  547. echo "Clone repository with tests"
  548. git branch: 'main',
  549. url: 'git@github.com:unacms/una-ui-test3.git',
  550. credentialsId: '0043feeb-9df7-4494-9b2b-d6c8a1b8ca08'
  551. // Create environment file
  552. sh '''
  553. cat > .env.local << EOF
  554. baseUrl=https://${DEPLOY_HTTP_HOST}${DEPLOY_HTTP_PATH}
  555. userAdminPwd=${TEST_USER_ADMIN_PWD}
  556. userRegularPwd=${TEST_USER_REGULAR_PWD}
  557. userTomPwd=${TEST_USER_TOM_PWD}
  558. EOF
  559. '''
  560. echo "Install dependences for UI tests"
  561. sh 'npm install'
  562. sh 'npx playwright install'
  563. echo "Running Playwright UI Tests"
  564. sh 'npm run test'
  565. }
  566. }
  567. }
  568. }
  569. post {
  570. always {
  571. // Archive test results
  572. archiveArtifacts artifacts: 'una-ui-test3/results/results.xml', allowEmptyArchive: true
  573. junit checksName: 'UI-Tests', testResults: 'una-ui-test3/results/results.xml'
  574. }
  575. }
  576. }
  577. // end
  578. }
  579. post {
  580. /*
  581. always {
  582. xunit checksName: 'UI-Tests', thresholds: [
  583. failed(failureNewThreshold: '0', failureThreshold: '0', unstableNewThreshold: '0', unstableThreshold: '0')
  584. ],
  585. tools: [
  586. JUnit(excludesPattern: '', pattern: 'una-ui-test3/results/results.xml', stopProcessingIfError: true)
  587. ]
  588. }
  589. */
  590. success {
  591. echo 'UNA CI/CD Pipeline completed successfully!'
  592. }
  593. failure {
  594. echo 'UNA CI/CD Pipeline failed!'
  595. script {
  596. emailext(
  597. subject: "Build Failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
  598. body: "Build failed!\nCheck console output at ${env.BUILD_URL}\n\nCommit author: ${env.CHANGE_AUTHOR ?: 'unknown'}",
  599. to: "${env.CHANGE_AUTHOR_EMAIL}"
  600. )
  601. slackSend(
  602. botUser: true,
  603. channel: '#unacms',
  604. color: '#ff4444',
  605. iconEmoji: '👮',
  606. message: "Build failed!\nCheck console output at ${env.BUILD_URL}\n\nCommit author: ${env.CHANGE_AUTHOR ?: 'unknown'}",
  607. notifyCommitters: true,
  608. tokenCredentialId: 'slack-jenkins-bot-token'
  609. )
  610. }
  611. }
  612. unstable {
  613. echo 'UNA CI/CD Pipeline completed with test failures!'
  614. }
  615. }
  616. }