From 3b8b84da4f7392b5280c1eb75d68627aaced999d Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Mon, 12 Jan 2026 13:39:14 +0530 Subject: [PATCH 1/9] Updated main.yml --- .github/workflows/main.yml | 106 ++++++++++++++++++++++++++++++++++--- 1 file changed, 100 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7617371e..838b439a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,11 +1,19 @@ -name: using mpm to install MATLAB -on: push +name: CI/CD Pipeline + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + jobs: - run-tests-job: + unit-tests: + name: Unit Tests (Push Only) + if: ${{ github.event_name == 'push' }} strategy: + fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - name: Run System tests runs-on: ${{ matrix.os }} steps: - name: Check out repository @@ -16,7 +24,7 @@ jobs: with: java-version: '17' distribution: 'temurin' - cache: maven + cache: 'maven' - name: Setup MATLAB id: setup-matlab @@ -26,4 +34,90 @@ jobs: run: mvn --batch-mode verify env: MATLAB_ROOT: ${{ steps.setup-matlab.outputs.matlabroot }} - MLM_LICENSE_TOKEN: ${{ secrets.MLM_LICENSE_TOKEN}} \ No newline at end of file + MLM_LICENSE_TOKEN: ${{ secrets.MLM_LICENSE_TOKEN }} + + system-verification: + name: System Verification + if: ${{ github.event_name == 'pull_request' }} + runs-on: self-hosted + defaults: + run: + shell: powershell + env: + JENKINS_URL: "http://localhost:8080" + JENKINS_USER: "guest" + JENKINS_TOKEN: ${{ secrets.JENKINS_TOKEN }} + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: 'maven' + + - name: Build Plugin + run: mvn package -DskipTests + + - name: Deploy Plugin via CLI + run: | + Write-Host "Downloading Jenkins CLI..." + Invoke-WebRequest -Uri "$env:JENKINS_URL/jnlpJars/jenkins-cli.jar" -OutFile "jenkins-cli.jar" + + $absPath = Convert-Path "target\matlab.hpi" + $fileUri = "file:///$($absPath.Replace('\', '/'))" + + Write-Host "Installing plugin from: $fileUri" + + $installCmd = "java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth $env:JENKINS_USER`:$env:JENKINS_TOKEN install-plugin $fileUri -deploy" + cmd /c $installCmd + + Write-Host "Plugin staged. Ignoring RestartRequiredException and proceeding to restart step..." + exit 0 + + - name: Restart Jenkins + run: | + Write-Host "Triggering Safe Restart..." + try { + java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth "$($env:JENKINS_USER):$($env:JENKINS_TOKEN)" safe-restart + } catch { + Write-Host "Restart command sent." + } + + Write-Host "Waiting for Jenkins to restart..." + Start-Sleep -Seconds 10 + $count = 0 + do { + Start-Sleep -Seconds 5 + $count++ + try { + $response = Invoke-WebRequest -Uri "$env:JENKINS_URL/login" -UseBasicParsing -ErrorAction Stop + if ($response.StatusCode -eq 200) { break } + } catch {} + + if ($count -gt 60) { + Write-Error "Timeout waiting for Jenkins to restart." + exit 1 + } + } while ($true) + Write-Host "Jenkins is back up." + + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Run Verifier Script + run: | + pip install python-jenkins + Write-Host "Running verification..." + python jenkins_verifier.py ` + --url $env:JENKINS_URL ` + --user $env:JENKINS_USER ` + --token $env:JENKINS_TOKEN ` + --job "test_project" \ No newline at end of file From e018e087e30d7e6263a2e5ba1929911aad5ff4da Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Mon, 12 Jan 2026 14:02:57 +0530 Subject: [PATCH 2/9] Updated main.yml --- jenkins_verifier.py | 169 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 jenkins_verifier.py diff --git a/jenkins_verifier.py b/jenkins_verifier.py new file mode 100644 index 00000000..c69c742d --- /dev/null +++ b/jenkins_verifier.py @@ -0,0 +1,169 @@ +import jenkins +import time +import argparse +import sys +import requests + +TEST_CONFIG = { + "ARTIFACT_NAME": "junittestresults.xml", + "EXPECTED_CONTENT": "testAddition", + "ARTIFACT_PATH": "matlabTestArtifacts/junittestresults.xml" +} + + +def trigger_build(server, job_name): + print(f"1. [ACTION] Triggering build for job: {job_name}") + queue_id = server.build_job(job_name) + print(f" -> Job queued. Queue ID: {queue_id}") + return queue_id + +def get_build_number(server, queue_id): + print(" -> Waiting for build to generate a build number...") + while True: + try: + queue_item = server.get_queue_item(queue_id) + if 'executable' in queue_item: + build_number = queue_item['executable']['number'] + print(f" -> Build started. Build Number: {build_number}") + return build_number + if queue_item.get('cancelled'): + print(" -> [ERROR] Build was cancelled in the queue.") + sys.exit(1) + except Exception as e: + print(f" -> Error checking queue: {e}") + time.sleep(2) + +def wait_for_completion(server, job_name, build_number): + print(f"2. [ACTION] Waiting for Build #{build_number} to complete...") + while True: + try: + build_info = server.get_build_info(job_name, build_number) + if not build_info['building']: + result = build_info['result'] + print(f" -> Build finished. Result: {result}") + return result + except Exception as e: + print(f" -> Polling error: {e}") + time.sleep(5) + +def verify_artifact_exists(server, job_name, build_number, filename): + print(f"\n3. [TEST] Artifact Generation Check") + print(f" -> Looking for artifact: '{filename}'") + try: + build_info = server.get_build_info(job_name, build_number) + artifacts = build_info.get('artifacts', []) + + if not artifacts: + print(" -> [DEBUG] Jenkins reports 0 artifacts archived.") + else: + print(f" -> [DEBUG] Found {len(artifacts)} artifact(s):") + for a in artifacts: + print(f" - FileName: '{a['fileName']}' | RelativePath: '{a['relativePath']}'") + + for artifact in artifacts: + if filename in artifact['fileName'] or filename in artifact['relativePath']: + print(f" -> [PASS] Artifact '{filename}' was generated successfully.") + return artifact + + print(f" -> [FAIL] Artifact '{filename}' NOT found in build.") + return None + except Exception as e: + print(f" -> [ERROR] Failed to fetch artifacts: {e}") + return None + +def verify_artifact_content(base_url, auth, job_name, build_number, artifact_path, expected_text): + print(f"\n4. [TEST] Artifact Content Access Check") + print(f" -> Downloading artifact to verify content...") + + base_url = base_url.rstrip('/') + + artifact_url = f"{base_url}/job/{job_name}/{build_number}/artifact/{artifact_path}" + print(f" -> Fetching URL: {artifact_url}") + + try: + response = requests.get(artifact_url, auth=auth) + + if response.status_code != 200: + print(f" -> [FAIL] HTTP Error {response.status_code}. Response: {response.text[:100]}") + return False + + text_content = response.text + + if expected_text in text_content: + print(f" -> Found expected text: '{expected_text}'") + print(f" -> [PASS] Content verification successful.") + return True + else: + print(f" -> [FAIL] Text '{expected_text}' NOT found.") + print(f" -> Actual Content Snippet: {text_content[:200]}...") + return False + except Exception as e: + print(f" -> [ERROR] Failed to download artifact: {e}") + return False + + +def main(): + parser = argparse.ArgumentParser(description="Jenkins Plugin Integration Test Suite") + parser.add_argument("--url", help="Jenkins Server URL") + parser.add_argument("--user", help="Jenkins User ID") + parser.add_argument("--token", help="Jenkins API Token") + parser.add_argument("--job", required=True, help="Job Name") + + args = parser.parse_args() + + jenkins_url = args.url or os.environ.get('JENKINS_URL') + jenkins_user = args.user or os.environ.get('JENKINS_USER') + jenkins_token = args.token or os.environ.get('JENKINS_TOKEN') + + if not all([jenkins_url, jenkins_user, jenkins_token]): + print("Error: Missing connection details (URL, User, or Token).") + sys.exit(1) + + try: + server = jenkins.Jenkins(jenkins_url, username=jenkins_user, password=jenkins_token) + user = server.get_whoami() + print(f"Connected to Jenkins as {user['fullName']}") + print("=========================================") + print("STARTING SEQUENTIAL INTEGRATION TESTS") + print("=========================================") + + queue_id = trigger_build(server, args.job) + build_number = get_build_number(server, queue_id) + result = wait_for_completion(server, args.job, build_number) + + if result != 'SUCCESS': + print(f"\n[CRITICAL FAIL] Build failed with status {result}. Stopping tests.") + sys.exit(1) + else: + print(f" -> [PASS] Basic Build Success") + + artifact_obj = verify_artifact_exists(server, args.job, build_number, TEST_CONFIG["ARTIFACT_NAME"]) + + if not artifact_obj: + print("\n[CRITICAL FAIL] Artifact generation failed. Stopping tests.") + sys.exit(1) + + content_ok = verify_artifact_content( + jenkins_url, + (jenkins_user, jenkins_token), + args.job, + build_number, + artifact_obj['relativePath'], + TEST_CONFIG["EXPECTED_CONTENT"] + ) + + if not content_ok: + print("\n[CRITICAL FAIL] Artifact content is incorrect.") + sys.exit(1) + + print("\n=========================================") + print("ALL TESTS PASSED SUCCESSFULLY") + print("=========================================") + sys.exit(0) + + except Exception as e: + print(f"An unexpected error occurred: {e}") + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file From 42800444b0864be29875b40161d731662b3872b6 Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Thu, 29 Jan 2026 15:40:08 +0530 Subject: [PATCH 3/9] Added cross-platform test --- .github/workflows/main.yml | 37 +++++++++---------- .../cross-platform-tests/jenkins_verifier.py | 0 2 files changed, 18 insertions(+), 19 deletions(-) rename jenkins_verifier.py => src/test/cross-platform-tests/jenkins_verifier.py (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 838b439a..7fb7c08c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,19 +1,15 @@ -name: CI/CD Pipeline - +name: using mpm to install MATLAB on: push: - branches: [ master ] pull_request: - branches: [ master ] jobs: - unit-tests: - name: Unit Tests (Push Only) - if: ${{ github.event_name == 'push' }} + run-tests-job: strategy: - fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] + name: Run System tests + if: ${{ github.event_name == 'push' }} runs-on: ${{ matrix.os }} steps: - name: Check out repository @@ -24,7 +20,7 @@ jobs: with: java-version: '17' distribution: 'temurin' - cache: 'maven' + cache: maven - name: Setup MATLAB id: setup-matlab @@ -34,10 +30,10 @@ jobs: run: mvn --batch-mode verify env: MATLAB_ROOT: ${{ steps.setup-matlab.outputs.matlabroot }} - MLM_LICENSE_TOKEN: ${{ secrets.MLM_LICENSE_TOKEN }} + MLM_LICENSE_TOKEN: ${{ secrets.MLM_LICENSE_TOKEN}} - system-verification: - name: System Verification + cross-platform-tests: + name: Cross Platform Tests if: ${{ github.event_name == 'pull_request' }} runs-on: self-hosted defaults: @@ -64,7 +60,7 @@ jobs: - name: Build Plugin run: mvn package -DskipTests - - name: Deploy Plugin via CLI + - name: Move Plugin to Machine run: | Write-Host "Downloading Jenkins CLI..." Invoke-WebRequest -Uri "$env:JENKINS_URL/jnlpJars/jenkins-cli.jar" -OutFile "jenkins-cli.jar" @@ -77,10 +73,10 @@ jobs: $installCmd = "java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth $env:JENKINS_USER`:$env:JENKINS_TOKEN install-plugin $fileUri -deploy" cmd /c $installCmd - Write-Host "Plugin staged. Ignoring RestartRequiredException and proceeding to restart step..." + Write-Host "Plugin staged." exit 0 - - name: Restart Jenkins + - name: Restart Jenkins Server run: | Write-Host "Triggering Safe Restart..." try { @@ -107,16 +103,19 @@ jobs: } while ($true) Write-Host "Jenkins is back up." - - name: Set up Python 3.11 + - name: Set up Python 3 uses: actions/setup-python@v4 with: - python-version: '3.11' + python-version: '3.x' - - name: Run Verifier Script + - name: Install dependencies run: | pip install python-jenkins + + - name: Run cross platform tests + run: | Write-Host "Running verification..." - python jenkins_verifier.py ` + python src\test\cross-platform-tests\jenkins_verifier.py ` --url $env:JENKINS_URL ` --user $env:JENKINS_USER ` --token $env:JENKINS_TOKEN ` diff --git a/jenkins_verifier.py b/src/test/cross-platform-tests/jenkins_verifier.py similarity index 100% rename from jenkins_verifier.py rename to src/test/cross-platform-tests/jenkins_verifier.py From efa1afa95a0e17e0dad2364929100d1dc3249b8a Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Thu, 29 Jan 2026 17:09:58 +0530 Subject: [PATCH 4/9] Added Cross Platform Test --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7fb7c08c..ae9e676a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,7 +33,7 @@ jobs: MLM_LICENSE_TOKEN: ${{ secrets.MLM_LICENSE_TOKEN}} cross-platform-tests: - name: Cross Platform Tests + name: Run Cross Platform Tests if: ${{ github.event_name == 'pull_request' }} runs-on: self-hosted defaults: From 4e5c30e2f58145beccdcf2dc7285e3643cb12a42 Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Fri, 30 Jan 2026 12:02:50 +0530 Subject: [PATCH 5/9] Updated main.yml --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ae9e676a..4d0cf97c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -78,7 +78,7 @@ jobs: - name: Restart Jenkins Server run: | - Write-Host "Triggering Safe Restart..." + Write-Host "Restarting Jenkins Server..." try { java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth "$($env:JENKINS_USER):$($env:JENKINS_TOKEN)" safe-restart } catch { @@ -101,7 +101,7 @@ jobs: exit 1 } } while ($true) - Write-Host "Jenkins is back up." + Write-Host "Jenkins Up." - name: Set up Python 3 uses: actions/setup-python@v4 From 11b916724129f90cf35bf8a59afed2040048cd01 Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Fri, 30 Jan 2026 12:07:37 +0530 Subject: [PATCH 6/9] Updated main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4d0cf97c..7d990c63 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -41,7 +41,7 @@ jobs: shell: powershell env: JENKINS_URL: "http://localhost:8080" - JENKINS_USER: "guest" + JENKINS_USER: "adutt" JENKINS_TOKEN: ${{ secrets.JENKINS_TOKEN }} steps: From 209ab2a8558387e9e12aa5ffb6631b802ef77145 Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Fri, 30 Jan 2026 17:57:45 +0530 Subject: [PATCH 7/9] Updated action file --- .github/workflows/main.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7d990c63..91818141 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,7 +1,5 @@ name: using mpm to install MATLAB -on: - push: - pull_request: +on: [push, pull_request] jobs: run-tests-job: @@ -80,7 +78,7 @@ jobs: run: | Write-Host "Restarting Jenkins Server..." try { - java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth "$($env:JENKINS_USER):$($env:JENKINS_TOKEN)" safe-restart + java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth "$($env:JENKINS_USER):$($env:JENKINS_TOKEN)" restart } catch { Write-Host "Restart command sent." } From f91b97b5b08f35e9c0a89d63b4350501c6a19c75 Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Fri, 30 Jan 2026 18:17:07 +0530 Subject: [PATCH 8/9] Updated action file --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 91818141..9175dadb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -68,7 +68,7 @@ jobs: Write-Host "Installing plugin from: $fileUri" - $installCmd = "java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth $env:JENKINS_USER`:$env:JENKINS_TOKEN install-plugin $fileUri -deploy" + $installCmd = "java -jar jenkins-cli.jar -s $env:JENKINS_URL -auth $env:JENKINS_USER`:$env:JENKINS_TOKEN install-plugin $fileUri" cmd /c $installCmd Write-Host "Plugin staged." From fa54dfaca17d4b2bec1df7f901314b2f3140e669 Mon Sep 17 00:00:00 2001 From: adutt-mw Date: Fri, 30 Jan 2026 18:41:40 +0530 Subject: [PATCH 9/9] Updated main.yml --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9175dadb..28082f1a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -53,7 +53,6 @@ jobs: with: java-version: '17' distribution: 'temurin' - cache: 'maven' - name: Build Plugin run: mvn package -DskipTests