diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index da08cdf..a400650 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,75 +23,78 @@ Cli Version Check: stage : Pre Checks image : alpine:latest before_script: - - apk add --no-cache curl git - script: | - # Define installation directory and version file path - export CLI_FOLDER="$(pwd)/veracode-cli" - export VERSION_FILE="$CLI_FOLDER/VERSION" - mkdir -p "${CLI_FOLDER}" - - # Fetch latest Veracode CLI version - echo "Fetching the latest Veracode CLI version" - export LATEST_CLI_VERSION=$(curl -s https://tools.veracode.com/veracode-cli/LATEST_VERSION) - - # Validate the fetched version - if [[ -z "$LATEST_CLI_VERSION" ]]; then - echo "Error: Failed to fetch latest version" - exit 1 - fi - echo "LATEST CLI VERSION: ${LATEST_CLI_VERSION}" - - # Get the locally installed version (if exists) - if [[ -f "${VERSION_FILE}" ]]; then - export LOCAL_CLI_VERSION=$(cat "${VERSION_FILE}") - echo "LOCAL CLI VERSION: ${LOCAL_CLI_VERSION}" - else - export LOCAL_CLI_VERSION="NONE" # Default if no version exists - fi - - # Compare versions and update only if they are different - if [[ "$LOCAL_CLI_VERSION" != "$LATEST_CLI_VERSION" ]]; then - echo "New version detected. Downloading Veracode CLI..." - - export CLI_DOWNLOAD_URL="https://tools.veracode.com/veracode-cli/veracode-cli_${LATEST_CLI_VERSION}_linux_x86.tar.gz" - echo "CLI DOWNLOAD URL: ${CLI_DOWNLOAD_URL}" - - # Download and extract the CLI - curl -s -L "${CLI_DOWNLOAD_URL}" -o "${CLI_FOLDER}/veracode-cli.tar.gz" - tar -xzf "${CLI_FOLDER}/veracode-cli.tar.gz" -C "${CLI_FOLDER}" - - # Move the extracted files into the install directory (flatten structure) - mv "$CLI_FOLDER/veracode-cli_${LATEST_CLI_VERSION}_linux_x86"/* "$CLI_FOLDER" - - # Clean up the tarball and extracted directory - rm -rf "$CLI_FOLDER/veracode-cli_${LATEST_CLI_VERSION}_linux_x86" - rm -f "$CLI_FOLDER/veracode-cli.tar.gz" - - # Verify the extracted files - echo "Files in install directory:" - ls -l "$CLI_FOLDER" - - echo "Setting up Git configuration" - git config --global user.name "veracode" - git config --global user.email "cli@veracode.com" - - git remote set-url origin "https://gitlab-ci-token:${PRIVATE_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git" - - echo "Checkout main" - git checkout main 2>/dev/null || echo "Conflicts prevent checkout, Continuing..." # Ensure we are on the main branch - - echo "git pull origin main" - if git pull origin main; then - git add "$CLI_FOLDER/*" - git commit -m "Update Veracode CLI version to ${LATEST_CLI_VERSION}" - echo "push origin main" - git push origin main || (git pull --rebase origin main && git push origin main) || echo "Push still failed, Due to other pipline updates" + - apk add --no-cache nodejs npm curl git + script: + - npm i + - node ./cancelOldPipeline.js + - | + # Define installation directory and version file path + export CLI_FOLDER="$(pwd)/veracode-cli" + export VERSION_FILE="$CLI_FOLDER/VERSION" + mkdir -p "${CLI_FOLDER}" + + # Fetch latest Veracode CLI version + echo "Fetching the latest Veracode CLI version" + export LATEST_CLI_VERSION=$(curl -s https://tools.veracode.com/veracode-cli/LATEST_VERSION) + + # Validate the fetched version + if [[ -z "$LATEST_CLI_VERSION" ]]; then + echo "Error: Failed to fetch latest version" + exit 1 + fi + echo "LATEST CLI VERSION: ${LATEST_CLI_VERSION}" + + # Get the locally installed version (if exists) + if [[ -f "${VERSION_FILE}" ]]; then + export LOCAL_CLI_VERSION=$(cat "${VERSION_FILE}") + echo "LOCAL CLI VERSION: ${LOCAL_CLI_VERSION}" else - echo "Veracode CLI is already exists." - fi - else - echo "Veracode CLI is already up to date. No update required." - fi + export LOCAL_CLI_VERSION="NONE" # Default if no version exists + fi + + # Compare versions and update only if they are different + if [[ "$LOCAL_CLI_VERSION" != "$LATEST_CLI_VERSION" ]]; then + echo "New version detected. Downloading Veracode CLI..." + + export CLI_DOWNLOAD_URL="https://tools.veracode.com/veracode-cli/veracode-cli_${LATEST_CLI_VERSION}_linux_x86.tar.gz" + echo "CLI DOWNLOAD URL: ${CLI_DOWNLOAD_URL}" + + # Download and extract the CLI + curl -s -L "${CLI_DOWNLOAD_URL}" -o "${CLI_FOLDER}/veracode-cli.tar.gz" + tar -xzf "${CLI_FOLDER}/veracode-cli.tar.gz" -C "${CLI_FOLDER}" + + # Move the extracted files into the install directory (flatten structure) + mv "$CLI_FOLDER/veracode-cli_${LATEST_CLI_VERSION}_linux_x86"/* "$CLI_FOLDER" + + # Clean up the tarball and extracted directory + rm -rf "$CLI_FOLDER/veracode-cli_${LATEST_CLI_VERSION}_linux_x86" + rm -f "$CLI_FOLDER/veracode-cli.tar.gz" + + # Verify the extracted files + echo "Files in install directory:" + ls -l "$CLI_FOLDER" + + echo "Setting up Git configuration" + git config --global user.name "veracode" + git config --global user.email "cli@veracode.com" + + git remote set-url origin "https://gitlab-ci-token:${PRIVATE_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git" + + echo "Checkout main" + git checkout main 2>/dev/null || echo "Conflicts prevent checkout, Continuing..." # Ensure we are on the main branch + + echo "git pull origin main" + if git pull origin main; then + git add "$CLI_FOLDER/*" + git commit -m "Update Veracode CLI version to ${LATEST_CLI_VERSION}" + echo "push origin main" + git push origin main || (git pull --rebase origin main && git push origin main) || echo "Push still failed, Due to other pipline updates" + else + echo "Veracode CLI is already exists." + fi + else + echo "Veracode CLI is already up to date. No update required." + fi only: - main artifacts: diff --git a/cancelOldPipeline.js b/cancelOldPipeline.js new file mode 100644 index 0000000..711423a --- /dev/null +++ b/cancelOldPipeline.js @@ -0,0 +1,60 @@ +const { fetchAllPipelines, getPipelineVariables, cancelPipeline } = require("./utility/service"); + +const hostName = process.env.CI_SERVER_HOST; +const projectId = process.env.CI_PROJECT_ID; +const pipelineName = process.env.PIPELINE_NAME; +const sourceBranch = process.env.SOURCE_BRANCH; +const currentPipelineId = process.env.CI_PIPELINE_ID; +const currentPipelineCreatedAt = process.env.CI_PIPELINE_CREATED_AT; + + +async function cancelOldPipeline() { + try { + console.log(`Using pipeline name: ${pipelineName}`); + console.log(`Current branch: ${sourceBranch}`); + + // Fetch running pipelines + const pipelines = await fetchAllPipelines(hostName, projectId, pipelineName); + + if (!pipelines || pipelines.length === 0) { + console.log("No running pipelines found. Nothing to cancel."); + return; + } + + for (const pipeline of pipelines) { + const pipelineId = pipeline.id; + + // Skip current pipeline itself + if (pipelineId === Number(currentPipelineId)) { + console.log(`Skipping current pipeline ${pipelineId}`); + continue; + } + + // Convert current pipeline creation time to epoch milliseconds + const currentEpoch = new Date(currentPipelineCreatedAt).getTime(); + const createdEpoch = new Date(pipeline.created_at).getTime(); + + // Skip newer pipelines + if (createdEpoch > currentEpoch) { + console.log(`Skipping newer pipeline ${pipelineId} created at ${pipeline.created_at}`); + continue; + } + + // Get pipeline variables + const vars = await getPipelineVariables(hostName, projectId, pipelineId) + + const pipelineBranch = vars.find(v => v.key === "SOURCE_BRANCH")?.value; + + if (pipelineBranch === sourceBranch) { + console.log(`Cancelling older pipeline ${pipelineId} created at ${pipeline.created_at}`); + await cancelPipeline(hostName, projectId, pipelineId) + } else { + console.log(`Pipeline ${pipelineId} branch ${pipelineBranch} does not match current branch ${sourceBranch}, skipping`); + } + } + } catch (error) { + console.log("Error cancelling pipelines:", error.response?.data || error.message); + } +} + +cancelOldPipeline(); diff --git a/utility/service.js b/utility/service.js index 25b9211..0b2eb59 100644 --- a/utility/service.js +++ b/utility/service.js @@ -124,4 +124,51 @@ async function createComment(projectUrl, mergeRequestId, eventName, commitSha, f } } -module.exports = {checkLabelExists, createLabels, createIssue, listExistingOpenIssues, createWikiPage, createComment} \ No newline at end of file +async function fetchAllPipelines(hostName, veracodeProjectId, pipelineName) { + let pipelines = []; + let page = 1; + while(page) { + try { + const url = `https://${hostName}/api/v4/projects/${veracodeProjectId}/pipelines` + const response = await axios.get(url, { + ...headers, + params: { + status: "running", + name: pipelineName, + per_page: 100, + page + } + }); + pipelines.push(...response.data); + page = Number(response.headers['x-next-page']); + } catch (error) { + console.log("Error while fetching all pipelines", error.response?.data || error.message); + break; + } + } + return pipelines; +} + +async function getPipelineVariables(hostName, veracodeProjectId, pipelineId) { + try { + const url = `https://${hostName}/api/v4/projects/${veracodeProjectId}/pipelines/${pipelineId}/variables` + const response = await axios.get(url, headers); + return response.data; + } catch (error) { + console.log("Error while fetching pipeline variable", error.response?.data || error.message); + return []; + } +} + +async function cancelPipeline(hostName, veracodeProjectId, pipelineId) { + try { + const url = `https://${hostName}/api/v4/projects/${veracodeProjectId}/pipelines/${pipelineId}/cancel` + const response = await axios.post(url, {}, headers); + return response.data; + } catch (error) { + console.log("Error while fetching pipeline variable", error.response?.data || error.message); + return null; + } +} + +module.exports = {checkLabelExists, createLabels, createIssue, listExistingOpenIssues, createWikiPage, createComment, fetchAllPipelines, getPipelineVariables, cancelPipeline} \ No newline at end of file diff --git a/veracode.yml b/veracode.yml index 3c64803..1cfc039 100644 --- a/veracode.yml +++ b/veracode.yml @@ -1,5 +1,3 @@ -debug: - false veracode_static_scan: push: trigger: true