From df4475eaaf342a2a25477ccf8ba30932d229937b Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Tue, 30 Sep 2025 14:53:02 +0200 Subject: [PATCH 01/46] Add SonarQube project configuration --- sonar-project.properties | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 sonar-project.properties diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 00000000..dbb92284 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,3 @@ +sonar.projectKey=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022 +sonar.projectName=Postiz App +sonar.projectDescription=An Open-Source Social Media Scheduler From 1aeebfce8f0f5acd7919a533e6b2248b30f310dc Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Tue, 30 Sep 2025 14:58:55 +0200 Subject: [PATCH 02/46] Enhance CI workflow with versioning and SonarQube analysis Added steps to get project version from Git tag and perform SonarQube analysis for both pull requests and branches. --- .github/workflows/build.yaml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 41464863..4b09db37 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -21,6 +21,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} + fetch-depth: 0 - name: Install pnpm uses: pnpm/action-setup@v2 @@ -48,3 +49,36 @@ jobs: - name: Build run: pnpm run build + + - name: Get Project Version from Git Tag + id: get_version + run: | + # Use 'git describe' to find the closest tag, falling back to the commit SHA if no tag is found. + # --tags includes all tags, --always ensures it always outputs something. + VERSION=$(git describe --tags --always) + echo "Project version is $VERSION" + echo "tag=$VERSION" >> $GITHUB_OUTPUT + + - name: SonarQube Analysis (Pull Request) + uses: SonarSource/sonarqube-scan-action@v6 + if: always() && github.event_name == 'pull_request' + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + + SONAR_PULL_REQUEST_KEY: ${{ github.event.pull_request.number }} + SONAR_PULL_REQUEST_BRANCH: ${{ github.head_ref }} + SONAR_PULL_REQUEST_BASE: ${{ github.base_ref }} + with: + args: > + -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} + + - name: SonarQube Analysis (Branch) + uses: SonarSource/sonarqube-scan-action@v6 + if: always() && github.event_name != 'pull_request' + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + with: + args: > + -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} From 92c7a6029976d9c994fd9239a14226dffe007983 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Tue, 30 Sep 2025 15:07:31 +0200 Subject: [PATCH 03/46] Update sonar-project.properties --- sonar-project.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sonar-project.properties b/sonar-project.properties index dbb92284..f036ddb5 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,3 +1,5 @@ sonar.projectKey=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022 sonar.projectName=Postiz App sonar.projectDescription=An Open-Source Social Media Scheduler + +sonar.javascript.node.maxspace=8192 From c2619d7cb414328ac437bc41bc5ba99874eb6025 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Tue, 30 Sep 2025 15:25:42 +0200 Subject: [PATCH 04/46] Update sonar.javascript.node.maxspace for performance Increased maximum node memory space for SonarQube scan performance. --- sonar-project.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index f036ddb5..c9aaeb56 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,4 +2,6 @@ sonar.projectKey=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022 sonar.projectName=Postiz App sonar.projectDescription=An Open-Source Social Media Scheduler -sonar.javascript.node.maxspace=8192 +# Scan Performace +sonar.javascript.node.maxspace=24576 +sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/*.spec.ts,**/*.test.ts From 4212e93a7cd99cf164abf1b09fa3911e774ce38b Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 10:03:04 +0200 Subject: [PATCH 05/46] Add fetch-depth option to checkout action --- .github/workflows/build.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4b09db37..f12b7ac3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -17,11 +17,12 @@ jobs: steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - fetch-depth: 0 - name: Install pnpm uses: pnpm/action-setup@v2 From 7fd69c23c579ba8abd1d49fa4de3b2fbb53cbebe Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 10:25:03 +0200 Subject: [PATCH 06/46] Add PNG files to sonar exclusions --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index c9aaeb56..5f07148d 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -4,4 +4,4 @@ sonar.projectDescription=An Open-Source Social Media Scheduler # Scan Performace sonar.javascript.node.maxspace=24576 -sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/*.spec.ts,**/*.test.ts +sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/*.spec.ts,**/*.test.ts,*.png From 520133342ef33d34c69454d4551380beb636ec53 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 10:42:59 +0200 Subject: [PATCH 07/46] update/build.yaml --- .github/workflows/build.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f12b7ac3..0005fd72 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,7 +3,7 @@ name: Build on: push: - pull_request: + pull_request_target: jobs: build: @@ -19,6 +19,14 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + if: always() && github.event_name == 'pull_request' + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + if: always() && github.event_name != 'pull_request' + - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: From 8cf266640d60b9508eeaca993a2fc1d901b21247 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 10:54:35 +0200 Subject: [PATCH 08/46] Remove PRs from build Will be a separate workflow. --- .github/workflows/build.yaml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0005fd72..cb442d6a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,7 +3,6 @@ name: Build on: push: - pull_request_target: jobs: build: @@ -19,13 +18,6 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.sha }} - if: always() && github.event_name == 'pull_request' - - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - if: always() && github.event_name != 'pull_request' - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 @@ -67,24 +59,9 @@ jobs: VERSION=$(git describe --tags --always) echo "Project version is $VERSION" echo "tag=$VERSION" >> $GITHUB_OUTPUT - - - name: SonarQube Analysis (Pull Request) - uses: SonarSource/sonarqube-scan-action@v6 - if: always() && github.event_name == 'pull_request' - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - - SONAR_PULL_REQUEST_KEY: ${{ github.event.pull_request.number }} - SONAR_PULL_REQUEST_BRANCH: ${{ github.head_ref }} - SONAR_PULL_REQUEST_BASE: ${{ github.base_ref }} - with: - args: > - -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} - name: SonarQube Analysis (Branch) uses: SonarSource/sonarqube-scan-action@v6 - if: always() && github.event_name != 'pull_request' env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} From 12da5b2f4fb82d8a37db1d298e3518158aa99c40 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 10:59:10 +0200 Subject: [PATCH 09/46] separate Workflow for PRs (Build) --- .github/workflows/build-pr.yml | 75 ++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .github/workflows/build-pr.yml diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml new file mode 100644 index 00000000..00e26a4e --- /dev/null +++ b/.github/workflows/build-pr.yml @@ -0,0 +1,75 @@ +--- +name: Build + +on: + pull_request_target: + +jobs: + build: + runs-on: ubuntu-latest + + + strategy: + matrix: + node-version: ['20.17.0'] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: | + ${{ env.STORE_PATH }} + ${{ github.workspace }}/.next/cache + key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + restore-keys: | + ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}- + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm run build + + - name: Get Project Version from Git Tag + id: get_version + run: | + # Use 'git describe' to find the closest tag, falling back to the commit SHA if no tag is found. + # --tags includes all tags, --always ensures it always outputs something. + VERSION=$(git describe --tags --always) + echo "Project version is $VERSION" + echo "tag=$VERSION" >> $GITHUB_OUTPUT + + - name: SonarQube Analysis (Pull Request) + uses: SonarSource/sonarqube-scan-action@v6 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + + SONAR_PULL_REQUEST_KEY: ${{ github.event.pull_request.number }} + SONAR_PULL_REQUEST_BRANCH: ${{ github.head_ref }} + SONAR_PULL_REQUEST_BASE: ${{ github.base_ref }} + with: + args: > + -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} From 2580b8ecdc6bde2cbe3f201f692c314d768c46cd Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 14:04:36 +0200 Subject: [PATCH 10/46] Add environment configuration for build job --- .github/workflows/build-pr.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 00e26a4e..e5ca699b 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -7,7 +7,9 @@ on: jobs: build: runs-on: ubuntu-latest - + + environment: + name: build-pr strategy: matrix: @@ -66,10 +68,9 @@ jobs: env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - - SONAR_PULL_REQUEST_KEY: ${{ github.event.pull_request.number }} - SONAR_PULL_REQUEST_BRANCH: ${{ github.head_ref }} - SONAR_PULL_REQUEST_BASE: ${{ github.base_ref }} with: args: > -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} + -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} + -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} + -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} From 3a1ada849818de260c25c46fb65c5acabe16be1b Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 14:07:15 +0200 Subject: [PATCH 11/46] Add environment for build-and-publish job Added environment configuration for build-pr. --- .github/workflows/pr-docker-build.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-docker-build.yml b/.github/workflows/pr-docker-build.yml index adfb8348..17eb5c04 100644 --- a/.github/workflows/pr-docker-build.yml +++ b/.github/workflows/pr-docker-build.yml @@ -9,10 +9,16 @@ permissions: write-all jobs: build-and-publish: runs-on: ubuntu-latest - + + environment: + name: build-pr + steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} - name: Log in to GitHub Container Registry uses: docker/login-action@v3 From 1c9739413df84575a8ad04f66b211ac3f935bfa9 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 14:31:47 +0200 Subject: [PATCH 12/46] Update README with SonarQube badges Added quality and reliability metrics from SonarQube to README. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 91350317..61c975d6 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,10 @@

+

+[![Quality Gate Status](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=alert_status&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) [![Maintainability Rating](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=software_quality_maintainability_rating&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) [![Reliability Rating](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=software_quality_reliability_rating&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) [![Security Rating](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=software_quality_security_rating&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) +

+

Your ultimate AI social media scheduling tool


From 84f7cc409ac640cf6069fc2f97aa10b0b7518aa5 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 14:32:39 +0200 Subject: [PATCH 13/46] Update SonarQube badges in README Updated SonarQube badge links and added new badges. --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 61c975d6..9f7b351a 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,18 @@

-[![Quality Gate Status](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=alert_status&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) [![Maintainability Rating](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=software_quality_maintainability_rating&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) [![Reliability Rating](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=software_quality_reliability_rating&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) [![Security Rating](https://sonarqube.ennogelhaus.de/api/project_badges/measure?project=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022&metric=software_quality_security_rating&token=sqb_4ef7409d8d3bb84ff51d945f5a62bc0df93895a9)](https://sonarqube.ennogelhaus.de/dashboard?id=gitroomhq_postiz-app_bd4cd369-af44-4d19-903b-c4bdb0b66022) + + Quality Gate Status + + + Maintainability Rating + + + Reliability Rating + + + Security Rating +

From b8c72002150bbcfb844e9b275b78c2bd9bf94851 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 14:33:23 +0200 Subject: [PATCH 14/46] Fix SonarQube badge URLs in README Updated SonarQube badge links with specific project tokens. --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9f7b351a..d59b6be0 100644 --- a/README.md +++ b/README.md @@ -19,20 +19,20 @@

-

+

From 39c6cba6ff6e829f18a89161d2a74a97dfe5cfd1 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 14:40:42 +0200 Subject: [PATCH 15/46] Change version retrieval to short commit SHA Updated the workflow to retrieve the short commit SHA instead of the project version from Git tags. --- .github/workflows/build.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index cb442d6a..d40e7f14 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -51,13 +51,12 @@ jobs: - name: Build run: pnpm run build - - name: Get Project Version from Git Tag + - name: Get Commit SHA (short) id: get_version run: | - # Use 'git describe' to find the closest tag, falling back to the commit SHA if no tag is found. - # --tags includes all tags, --always ensures it always outputs something. - VERSION=$(git describe --tags --always) - echo "Project version is $VERSION" + # Get the short 8-character commit SHA + VERSION=$(git rev-parse --short=8 HEAD) + echo "Commit SHA is $VERSION" echo "tag=$VERSION" >> $GITHUB_OUTPUT - name: SonarQube Analysis (Branch) From 07074e76a83cb70134a42a3c4215385923403082 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 14:40:55 +0200 Subject: [PATCH 16/46] Update build-pr.yml --- .github/workflows/build-pr.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index e5ca699b..4cbfe2b2 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -54,13 +54,12 @@ jobs: - name: Build run: pnpm run build - - name: Get Project Version from Git Tag + - name: Get Commit SHA (short) id: get_version run: | - # Use 'git describe' to find the closest tag, falling back to the commit SHA if no tag is found. - # --tags includes all tags, --always ensures it always outputs something. - VERSION=$(git describe --tags --always) - echo "Project version is $VERSION" + # Get the short 8-character commit SHA + VERSION=$(git rev-parse --short=8 HEAD) + echo "Commit SHA is $VERSION" echo "tag=$VERSION" >> $GITHUB_OUTPUT - name: SonarQube Analysis (Pull Request) From cad9bfa4b68bf8f10067bf8008693004d89d4aa1 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 21:27:54 +0200 Subject: [PATCH 17/46] Add GitHub Actions workflow for PR builds --- .github/workflows/build-pr-temp.yml | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/build-pr-temp.yml diff --git a/.github/workflows/build-pr-temp.yml b/.github/workflows/build-pr-temp.yml new file mode 100644 index 00000000..e5c45d59 --- /dev/null +++ b/.github/workflows/build-pr-temp.yml @@ -0,0 +1,71 @@ +--- +name: Build + +on: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: ['20.17.0'] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: | + ${{ env.STORE_PATH }} + ${{ github.workspace }}/.next/cache + key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + restore-keys: | + ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}- + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm run build + + - name: Get Commit SHA (short) + id: get_version + run: | + # Get the short 8-character commit SHA + VERSION=$(git rev-parse --short=8 HEAD) + echo "Commit SHA is $VERSION" + echo "tag=$VERSION" >> $GITHUB_OUTPUT + + - name: SonarQube Analysis (Pull Request) + uses: SonarSource/sonarqube-scan-action@v6 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + with: + args: > + -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} + -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} + -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} + -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} From a6d4f075b208d2ddf70c8a915494fe4dd27ded63 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 21:36:22 +0200 Subject: [PATCH 18/46] Delete .github/workflows/build-pr-temp.yml --- .github/workflows/build-pr-temp.yml | 71 ----------------------------- 1 file changed, 71 deletions(-) delete mode 100644 .github/workflows/build-pr-temp.yml diff --git a/.github/workflows/build-pr-temp.yml b/.github/workflows/build-pr-temp.yml deleted file mode 100644 index e5c45d59..00000000 --- a/.github/workflows/build-pr-temp.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -name: Build - -on: - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: ['20.17.0'] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 8 - run_install: false - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: | - ${{ env.STORE_PATH }} - ${{ github.workspace }}/.next/cache - key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} - restore-keys: | - ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}- - - - name: Install dependencies - run: pnpm install - - - name: Build - run: pnpm run build - - - name: Get Commit SHA (short) - id: get_version - run: | - # Get the short 8-character commit SHA - VERSION=$(git rev-parse --short=8 HEAD) - echo "Commit SHA is $VERSION" - echo "tag=$VERSION" >> $GITHUB_OUTPUT - - - name: SonarQube Analysis (Pull Request) - uses: SonarSource/sonarqube-scan-action@v6 - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - with: - args: > - -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} - -Dsonar.pullrequest.key=${{ github.event.pull_request.number }} - -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} - -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} From 1127879b3020f13df83991a12f47a9f8b1b58b0d Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 21:37:36 +0200 Subject: [PATCH 19/46] Add SonarQube host URL to properties file --- sonar-project.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sonar-project.properties b/sonar-project.properties index 5f07148d..04171928 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -5,3 +5,5 @@ sonar.projectDescription=An Open-Source Social Media Scheduler # Scan Performace sonar.javascript.node.maxspace=24576 sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/*.spec.ts,**/*.test.ts,*.png + +sonar.host.url=https://sonarqube.ennogelhaus.de/ From 5f9e8012f6caf9f8b57c1ffba850c4929782a129 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 21:38:06 +0200 Subject: [PATCH 20/46] Change pull_request_target to pull_request event --- .github/workflows/build-pr.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 4cbfe2b2..22f07a53 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -2,15 +2,12 @@ name: Build on: - pull_request_target: + pull_request: jobs: build: runs-on: ubuntu-latest - environment: - name: build-pr - strategy: matrix: node-version: ['20.17.0'] @@ -20,7 +17,6 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.sha }} - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 @@ -64,9 +60,6 @@ jobs: - name: SonarQube Analysis (Pull Request) uses: SonarSource/sonarqube-scan-action@v6 - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} with: args: > -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} From 1f14c8690d5cf4886ff8ad47bad4819eac7cd353 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 21:46:10 +0200 Subject: [PATCH 21/46] Update build-pr.yml --- .github/workflows/build-pr.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 22f07a53..e5c45d59 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -60,6 +60,9 @@ jobs: - name: SonarQube Analysis (Pull Request) uses: SonarSource/sonarqube-scan-action@v6 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} with: args: > -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} From 6d7ed26e3c494db9ffe786b3e4a63d9e24a3f205 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 21:49:10 +0200 Subject: [PATCH 22/46] Update build-pr.yml --- .github/workflows/build-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index e5c45d59..70fa4373 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -61,8 +61,8 @@ jobs: - name: SonarQube Analysis (Pull Request) uses: SonarSource/sonarqube-scan-action@v6 env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_TOKEN: ${{ vars.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }} with: args: > -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} From 0b3f559cf5f44aa4f94acddd6eb94b5f4dc7e931 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 21:55:36 +0200 Subject: [PATCH 23/46] Add environment name to build PR workflow --- .github/workflows/build-pr.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 70fa4373..1dbd85b3 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -13,6 +13,9 @@ jobs: node-version: ['20.17.0'] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + environment: + name: build-pr + steps: - uses: actions/checkout@v4 with: From 39f617a54aa8a6b2e690824e62481d41f0275863 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 22:03:44 +0200 Subject: [PATCH 24/46] Update sonar-project.properties --- sonar-project.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sonar-project.properties b/sonar-project.properties index 04171928..884703b3 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -7,3 +7,6 @@ sonar.javascript.node.maxspace=24576 sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/*.spec.ts,**/*.test.ts,*.png sonar.host.url=https://sonarqube.ennogelhaus.de/ + +# This Token only has read permissions to analysis creation to Postiu App +sonar.login=sqp_a62bce8d2d33a7b751ae194353f8174b5563053c From 74afd9149c86732f4211ad29d84f245dc8625ccf Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 22:04:37 +0200 Subject: [PATCH 25/46] Remove SONAR_TOKEN and SONAR_HOST_URL from workflow Removed environment variables for SonarQube analysis. --- .github/workflows/build-pr.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 1dbd85b3..513fe803 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -63,9 +63,6 @@ jobs: - name: SonarQube Analysis (Pull Request) uses: SonarSource/sonarqube-scan-action@v6 - env: - SONAR_TOKEN: ${{ vars.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }} with: args: > -Dsonar.projectVersion=${{ steps.get_version.outputs.tag }} From 313830806627da9d4df541cc97945512f5175cec Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Wed, 1 Oct 2025 22:10:31 +0200 Subject: [PATCH 26/46] Update SonarQube authentication method Replaced sonar.login with sonar.token for authentication. --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index 884703b3..d61ed3a8 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -9,4 +9,4 @@ sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/*.s sonar.host.url=https://sonarqube.ennogelhaus.de/ # This Token only has read permissions to analysis creation to Postiu App -sonar.login=sqp_a62bce8d2d33a7b751ae194353f8174b5563053c +sonar.token=sqp_a62bce8d2d33a7b751ae194353f8174b5563053c From 7becf450eded6495d0089436c572db2683349ab9 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Thu, 2 Oct 2025 07:49:25 +0200 Subject: [PATCH 27/46] sonar-project.properties --- sonar-project.properties | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index d61ed3a8..5f07148d 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -5,8 +5,3 @@ sonar.projectDescription=An Open-Source Social Media Scheduler # Scan Performace sonar.javascript.node.maxspace=24576 sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/*.spec.ts,**/*.test.ts,*.png - -sonar.host.url=https://sonarqube.ennogelhaus.de/ - -# This Token only has read permissions to analysis creation to Postiu App -sonar.token=sqp_a62bce8d2d33a7b751ae194353f8174b5563053c From 477366164c5f9430d44f354bcd0312d11a9159fa Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:24:01 +0200 Subject: [PATCH 28/46] Remove legacy CI/CD configurations and implement new workflows for building and analyzing Node.js applications with SonarQube --- .github/workflows/{build.yaml => build} | 0 .github/workflows/{build-pr.yml => build-pr} | 0 Jenkins/Build.Jenkinsfile | 104 ++++++++++++++++++ Jenkins/BuildPR.Jenkinsfile | 108 +++++++++++++++++++ Jenkinsfile | 70 ------------ 5 files changed, 212 insertions(+), 70 deletions(-) rename .github/workflows/{build.yaml => build} (100%) rename .github/workflows/{build-pr.yml => build-pr} (100%) create mode 100644 Jenkins/Build.Jenkinsfile create mode 100644 Jenkins/BuildPR.Jenkinsfile delete mode 100644 Jenkinsfile diff --git a/.github/workflows/build.yaml b/.github/workflows/build similarity index 100% rename from .github/workflows/build.yaml rename to .github/workflows/build diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr similarity index 100% rename from .github/workflows/build-pr.yml rename to .github/workflows/build-pr diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile new file mode 100644 index 00000000..75228a90 --- /dev/null +++ b/Jenkins/Build.Jenkinsfile @@ -0,0 +1,104 @@ +// Declarative Pipeline for building Node.js application and running SonarQube analysis. +pipeline { + // Defines the execution environment. Replace 'linux-agent' with your specific agent label. + agent { + label 'linux-agent' + } + + // Configure options, primarily to ensure full Git history is fetched for SonarQube and versioning. + options { + // Skip the default checkout to manage it explicitly and ensure fetch-depth: 0. + skipDefaultCheckout() + } + + stages { + // Stage 1: Checkout the code with full history (fetch-depth: 0) + stage('Source Checkout') { + steps { + script { + // This performs a deep clone (fetch-depth: 0) + // NOTE: You must replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID + // that has access to your repository. If using Anonymous checkout, remove the credentialsId line. + checkout([ + $class: 'GitSCM', + branches: [[name: 'HEAD']], + extensions: [ + [$class: 'WipeWorkspace'], + [$class: 'CleanBeforeCheckout'], + [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] + ], + userRemoteConfigs: [ + [url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed + ] + ]) + } + } + } + + // Stage 2: Setup Node.js v20 and install pnpm + stage('Setup Environment') { + steps { + sh ''' + # Install Node.js v20 (closest matching the specified version '20.17.0') + # This uses Nodesource to ensure a specific major version is available. + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt-get install -y nodejs + + echo "Node.js version: \$(node -v)" + + # Install pnpm globally (version 8) + npm install -g pnpm@8 + echo "pnpm version: \$(pnpm -v)" + ''' + + // Skipping the complex pnpm cache setup as it relies on specific GitHub Actions features. + // In Jenkins, artifact caching is typically handled differently (e.g., using dedicated workspace cache plugins). + } + } + + // Stage 3: Install dependencies and build the application + stage('Install and Build') { + steps { + sh 'pnpm install' + sh 'pnpm run build' + } + } + + // Stage 4: Retrieve secrets from Vault and run SonarQube analysis + stage('SonarQube Analysis') { + steps { + script { + // 1. Get the short 8-character commit SHA for project versioning + def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() + echo "Commit SHA (short) is: ${commitShaShort}" + + // 2. Retrieve secrets from HashiCorp Vault using the dedicated plugin binding. + // The secret values will be available as the environment variables SONAR_TOKEN and SONAR_HOST_URL + // only within this 'withCredentials' block. + withCredentials([ + // The $class: 'VaultSecretCredentialsBinding' requires the Jenkins HashiCorp Vault Plugin + [$class: 'VaultSecretCredentialsBinding', + vaultSecrets: [ + // Map key 'SONAR_TOKEN' from Vault path 'postiz/data/ci/sonar' to Jenkins environment variable 'SONAR_TOKEN' + [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_TOKEN', envVar: 'SONAR_TOKEN'], + // Map key 'SONAR_HOST_URL' from Vault path 'postiz/data/ci/sonar' to Jenkins environment variable 'SONAR_HOST_URL' + [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_HOST_URL', envVar: 'SONAR_HOST_URL'] + ]] + ]) { + // 3. Execute sonar-scanner CLI + // NOTE: sonar-scanner must be installed and available on the agent's PATH, + // or configured via Jenkins' Global Tool Configuration. + sh """ + echo "Starting SonarQube Analysis for project version: ${commitShaShort}" + sonar-scanner \\ + -Dsonar.projectVersion=${commitShaShort} \\ + -Dsonar.token=\${SONAR_TOKEN} \\ + -Dsonar.host.url=\${SONAR_HOST_URL} + # Add other analysis properties here if needed (e.g., -Dsonar.projectKey=...) + """ + } + } + } + } + } +} diff --git a/Jenkins/BuildPR.Jenkinsfile b/Jenkins/BuildPR.Jenkinsfile new file mode 100644 index 00000000..12be0457 --- /dev/null +++ b/Jenkins/BuildPR.Jenkinsfile @@ -0,0 +1,108 @@ +// Declarative Pipeline for building Node.js application and running SonarQube analysis for a Pull Request. +pipeline { + // Defines the execution environment. Replace 'linux-agent' with your specific agent label. + agent { + label 'linux-agent' + } + + // Configure options, primarily to ensure full Git history is fetched for SonarQube and versioning. + options { + // Skip the default checkout to manage it explicitly and ensure fetch-depth: 0. + skipDefaultCheckout() + } + + // Environment variables that hold PR details (set automatically by Jenkins SCM plugins like Git/GitHub Branch Source) + environment { + // These variables are provided by Jenkins (e.g., in a Multibranch Pipeline setup) + // CHANGE_ID corresponds to ${{ github.event.pull_request.number }} + // CHANGE_BRANCH corresponds to ${{ github.event.pull_request.head.ref }} + // CHANGE_TARGET corresponds to ${{ github.event.pull_request.base.ref }} + PR_KEY = env.CHANGE_ID + PR_BRANCH = env.CHANGE_BRANCH + PR_BASE = env.CHANGE_TARGET + } + + stages { + // Stage 1: Checkout the code with full history (fetch-depth: 0) + stage('Source Checkout') { + steps { + script { + // This performs a deep clone (fetch-depth: 0) + // NOTE: You must replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID + // that has access to your repository. + checkout([ + $class: 'GitSCM', + branches: [[name: 'HEAD']], + extensions: [ + [$class: 'WipeWorkspace'], + [$class: 'CleanBeforeCheckout'], + [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] + ], + userRemoteConfigs: [ + [url: env.GIT_URL ?: ''] + ] + ]) + } + } + } + + // Stage 2: Setup Node.js v20 and install pnpm + stage('Setup Environment') { + steps { + sh ''' + # Install Node.js v20 (closest matching the specified version '20.17.0') + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt-get install -y nodejs + + echo "Node.js version: \$(node -v)" + + # Install pnpm globally (version 8) + npm install -g pnpm@8 + echo "pnpm version: \$(pnpm -v)" + ''' + } + } + + // Stage 3: Install dependencies and build the application + stage('Install and Build') { + steps { + sh 'pnpm install' + sh 'pnpm run build' + } + } + + // Stage 4: Retrieve secrets from Vault and run SonarQube PR analysis + stage('SonarQube Pull Request Analysis') { + steps { + script { + // 1. Get the short 8-character commit SHA for project versioning + def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() + echo "Commit SHA (short) is: ${commitShaShort}" + + // 2. Retrieve secrets from HashiCorp Vault using the dedicated plugin binding. + withCredentials([ + // Requires the Jenkins HashiCorp Vault Plugin + [$class: 'VaultSecretCredentialsBinding', + vaultSecrets: [ + [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_TOKEN', envVar: 'SONAR_TOKEN'], + [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_HOST_URL', envVar: 'SONAR_HOST_URL'] + ]] + ]) { + // 3. Execute sonar-scanner CLI with Pull Request parameters + sh """ + echo "Starting SonarQube Pull Request Analysis for PR #${PR_KEY}" + sonar-scanner \\ + -Dsonar.projectVersion=${commitShaShort} \\ + -Dsonar.token=\${SONAR_TOKEN} \\ + -Dsonar.host.url=\${SONAR_HOST_URL} \\ + -Dsonar.pullrequest.key=${PR_KEY} \\ + -Dsonar.pullrequest.branch=${PR_BRANCH} \\ + -Dsonar.pullrequest.base=${PR_BASE} + # Add other analysis properties here if needed (e.g., -Dsonar.projectKey=...) + """ + } + } + } + } + } +} diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index e7a614d0..00000000 --- a/Jenkinsfile +++ /dev/null @@ -1,70 +0,0 @@ -pipeline { - agent any - - environment { - NODE_VERSION = '20.17.0' - PR_NUMBER = "${env.CHANGE_ID}" // PR number comes from webhook payload - IMAGE_TAG="ghcr.io/gitroomhq/postiz-app-pr:${env.CHANGE_ID}" - } - - stages { - stage('Checkout Repository') { - steps { - checkout scm - } - } - - stage('Check Node.js and npm') { - steps { - script { - sh "node -v" - sh "npm -v" - } - } - } - - stage('Install Dependencies') { - steps { - sh 'npm ci' - } - } - - stage('Build Project') { - steps { - sh 'npm run build' - } - } - - stage('Build and Push Docker Image') { - when { - expression { return env.CHANGE_ID != null } // Only run if it's a PR - } - steps { - withCredentials([string(credentialsId: 'gh-pat', variable: 'GITHUB_PASS')]) { - // Docker login step - sh ''' - echo "$GITHUB_PASS" | docker login ghcr.io -u "egelhaus" --password-stdin - ''' - // Build Docker image - sh ''' - docker build -f Dockerfile.dev -t $IMAGE_TAG . - ''' - // Push Docker image to GitHub Container Registry - sh ''' - docker push $IMAGE_TAG - ''' - } - } - } - } - post { - success { - echo 'Build completed successfully!' - - } - failure { - echo 'Build failed!' - - } - } -} From ebbb64b9d89c5760ee3d9e623f28f32659bd6544 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:28:05 +0200 Subject: [PATCH 29/46] Enhance Jenkins pipeline comments and update Git checkout configuration for clarity and accuracy --- Jenkins/Build.Jenkinsfile | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 75228a90..923bb392 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -1,4 +1,4 @@ -// Declarative Pipeline for building Node.js application and running SonarQube analysis. +// Declarative Pipeline for building Node.js application and running SonarQube analysis triggered by a push event. pipeline { // Defines the execution environment. Replace 'linux-agent' with your specific agent label. agent { @@ -17,8 +17,8 @@ pipeline { steps { script { // This performs a deep clone (fetch-depth: 0) - // NOTE: You must replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID - // that has access to your repository. If using Anonymous checkout, remove the credentialsId line. + // NOTE: Replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID + // that has access to your repository. checkout([ $class: 'GitSCM', branches: [[name: 'HEAD']], @@ -28,7 +28,7 @@ pipeline { [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] ], userRemoteConfigs: [ - [url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed + [credentialsId: 'YOUR_GIT_CREDENTIALS_ID', url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed ] ]) } @@ -42,6 +42,7 @@ pipeline { # Install Node.js v20 (closest matching the specified version '20.17.0') # This uses Nodesource to ensure a specific major version is available. curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt-get update sudo apt-get install -y nodejs echo "Node.js version: \$(node -v)" @@ -50,9 +51,6 @@ pipeline { npm install -g pnpm@8 echo "pnpm version: \$(pnpm -v)" ''' - - // Skipping the complex pnpm cache setup as it relies on specific GitHub Actions features. - // In Jenkins, artifact caching is typically handled differently (e.g., using dedicated workspace cache plugins). } } @@ -73,10 +71,8 @@ pipeline { echo "Commit SHA (short) is: ${commitShaShort}" // 2. Retrieve secrets from HashiCorp Vault using the dedicated plugin binding. - // The secret values will be available as the environment variables SONAR_TOKEN and SONAR_HOST_URL - // only within this 'withCredentials' block. withCredentials([ - // The $class: 'VaultSecretCredentialsBinding' requires the Jenkins HashiCorp Vault Plugin + // Requires the Jenkins HashiCorp Vault Plugin [$class: 'VaultSecretCredentialsBinding', vaultSecrets: [ // Map key 'SONAR_TOKEN' from Vault path 'postiz/data/ci/sonar' to Jenkins environment variable 'SONAR_TOKEN' @@ -86,8 +82,6 @@ pipeline { ]] ]) { // 3. Execute sonar-scanner CLI - // NOTE: sonar-scanner must be installed and available on the agent's PATH, - // or configured via Jenkins' Global Tool Configuration. sh """ echo "Starting SonarQube Analysis for project version: ${commitShaShort}" sonar-scanner \\ From 762384d45ee572f71898f3d4f1161ce25dab0e7c Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:32:30 +0200 Subject: [PATCH 30/46] Refactor Jenkins pipeline to use 'agent any' for improved flexibility in execution environment --- Jenkins/Build.Jenkinsfile | 4 +--- Jenkins/BuildPR.Jenkinsfile | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 923bb392..b4924c91 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -1,9 +1,7 @@ // Declarative Pipeline for building Node.js application and running SonarQube analysis triggered by a push event. pipeline { // Defines the execution environment. Replace 'linux-agent' with your specific agent label. - agent { - label 'linux-agent' - } + agent any // Configure options, primarily to ensure full Git history is fetched for SonarQube and versioning. options { diff --git a/Jenkins/BuildPR.Jenkinsfile b/Jenkins/BuildPR.Jenkinsfile index 12be0457..49a6b868 100644 --- a/Jenkins/BuildPR.Jenkinsfile +++ b/Jenkins/BuildPR.Jenkinsfile @@ -1,10 +1,7 @@ // Declarative Pipeline for building Node.js application and running SonarQube analysis for a Pull Request. pipeline { // Defines the execution environment. Replace 'linux-agent' with your specific agent label. - agent { - label 'linux-agent' - } - + agent any // Configure options, primarily to ensure full Git history is fetched for SonarQube and versioning. options { // Skip the default checkout to manage it explicitly and ensure fetch-depth: 0. From 6e19591998eed889a0acf73876531ad18f0f6685 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:35:15 +0200 Subject: [PATCH 31/46] Remove unnecessary options configuration from Jenkins pipeline for cleaner setup --- Jenkins/Build.Jenkinsfile | 6 ------ Jenkins/BuildPR.Jenkinsfile | 5 ----- 2 files changed, 11 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index b4924c91..34d1d059 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -3,12 +3,6 @@ pipeline { // Defines the execution environment. Replace 'linux-agent' with your specific agent label. agent any - // Configure options, primarily to ensure full Git history is fetched for SonarQube and versioning. - options { - // Skip the default checkout to manage it explicitly and ensure fetch-depth: 0. - skipDefaultCheckout() - } - stages { // Stage 1: Checkout the code with full history (fetch-depth: 0) stage('Source Checkout') { diff --git a/Jenkins/BuildPR.Jenkinsfile b/Jenkins/BuildPR.Jenkinsfile index 49a6b868..3840b726 100644 --- a/Jenkins/BuildPR.Jenkinsfile +++ b/Jenkins/BuildPR.Jenkinsfile @@ -2,11 +2,6 @@ pipeline { // Defines the execution environment. Replace 'linux-agent' with your specific agent label. agent any - // Configure options, primarily to ensure full Git history is fetched for SonarQube and versioning. - options { - // Skip the default checkout to manage it explicitly and ensure fetch-depth: 0. - skipDefaultCheckout() - } // Environment variables that hold PR details (set automatically by Jenkins SCM plugins like Git/GitHub Branch Source) environment { From 789c4b4c7eb7ab050a243ebceca23e971d5c8015 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:41:42 +0200 Subject: [PATCH 32/46] Refactor Jenkins pipeline to improve Git checkout process and ensure necessary dependencies are installed --- Jenkins/Build.Jenkinsfile | 48 ++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 34d1d059..9c73c399 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -1,29 +1,36 @@ // Declarative Pipeline for building Node.js application and running SonarQube analysis triggered by a push event. pipeline { - // Defines the execution environment. Replace 'linux-agent' with your specific agent label. - agent any + // Defines the execution environment. Using 'agent any' to ensure an agent is available. + agent any stages { // Stage 1: Checkout the code with full history (fetch-depth: 0) stage('Source Checkout') { steps { - script { - // This performs a deep clone (fetch-depth: 0) - // NOTE: Replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID - // that has access to your repository. - checkout([ - $class: 'GitSCM', - branches: [[name: 'HEAD']], - extensions: [ - [$class: 'WipeWorkspace'], - [$class: 'CleanBeforeCheckout'], - [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] - ], - userRemoteConfigs: [ - [credentialsId: 'YOUR_GIT_CREDENTIALS_ID', url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed - ] - ]) - } + // STEP 1: Install Git and other necessary system dependencies first. + // This command ensures the 'git' command is available on the agent's PATH, + // which is the root cause of the previous 'No such file or directory' error. + sh ''' + echo "Ensuring git, curl, and build tools are installed..." + sudo apt-get update + sudo apt-get install -y git curl build-essential + ''' + + // STEP 2: Perform the deep clone checkout using the installed Git. + // NOTE: Replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID + // that has access to your repository. + checkout([ + $class: 'GitSCM', + branches: [[name: 'HEAD']], + extensions: [ + [$class: 'WipeWorkspace'], + [$class: 'CleanBeforeCheckout'], + [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] + ], + userRemoteConfigs: [ + [url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed + ] + ]) } } @@ -32,7 +39,6 @@ pipeline { steps { sh ''' # Install Node.js v20 (closest matching the specified version '20.17.0') - # This uses Nodesource to ensure a specific major version is available. curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get update sudo apt-get install -y nodejs @@ -69,7 +75,7 @@ pipeline { vaultSecrets: [ // Map key 'SONAR_TOKEN' from Vault path 'postiz/data/ci/sonar' to Jenkins environment variable 'SONAR_TOKEN' [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_TOKEN', envVar: 'SONAR_TOKEN'], - // Map key 'SONAR_HOST_URL' from Vault path 'postiz/data/ci/sonar' to Jenkins environment variable 'SONAR_HOST_URL' + // Map key 'SONAR_HOST_URL' from Vault path 'postiz/data/ci/sonar', to Jenkins environment variable 'SONAR_HOST_URL'] [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_HOST_URL', envVar: 'SONAR_HOST_URL'] ]] ]) { From febfb1e7d62a7cd8838672bc03c6f5f3543e9296 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:44:05 +0200 Subject: [PATCH 33/46] Refactor Jenkins pipeline to remove unnecessary Git installation steps and enhance apt command execution with retry logic --- Jenkins/Build.Jenkinsfile | 47 +++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 9c73c399..f90a7480 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -7,16 +7,10 @@ pipeline { // Stage 1: Checkout the code with full history (fetch-depth: 0) stage('Source Checkout') { steps { - // STEP 1: Install Git and other necessary system dependencies first. - // This command ensures the 'git' command is available on the agent's PATH, - // which is the root cause of the previous 'No such file or directory' error. - sh ''' - echo "Ensuring git, curl, and build tools are installed..." - sudo apt-get update - sudo apt-get install -y git curl build-essential - ''' + // Since 'git' is confirmed to be installed on agent2 (per log 'git version 2.43.0'), + // we remove the apt-get installation command which was failing due to a lock. - // STEP 2: Perform the deep clone checkout using the installed Git. + // STEP: Perform the deep clone checkout using the existing Git executable. // NOTE: Replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID // that has access to your repository. checkout([ @@ -28,7 +22,7 @@ pipeline { [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] ], userRemoteConfigs: [ - [url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed + [credentialsId: 'YOUR_GIT_CREDENTIALS_ID', url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed ] ]) } @@ -38,14 +32,39 @@ pipeline { stage('Setup Environment') { steps { sh ''' - # Install Node.js v20 (closest matching the specified version '20.17.0') + ATTEMPTS=0 + MAX_ATTEMPTS=5 + + # Function to robustly run apt commands with retries in case of lock conflict + install_with_retry() { + CMD=\$1 + ATTEMPTS=0 + while [ \$ATTEMPTS -lt \$MAX_ATTEMPTS ]; do + if sudo apt-get update && \$CMD; then + return 0 # Success + else + ATTEMPTS=\$((ATTEMPTS + 1)) + if [ \$ATTEMPTS -lt \$MAX_ATTEMPTS ]; then + echo "Apt lock detected or command failed. Retrying in 5 seconds (Attempt \$ATTEMPTS of \$MAX_ATTEMPTS)..." + sleep 5 + fi + fi + done + echo "Failed to execute apt command after \$MAX_ATTEMPTS attempts." + return 1 # Failure + } + + # 1. Install curl (required for NodeSource script) + install_with_retry "sudo apt-get install -y curl" || exit 1 + + # 2. Install Node.js v20 (closest matching the specified version '20.17.0') + # This step uses curl (installed above) and needs its own apt-get execution. curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - - sudo apt-get update - sudo apt-get install -y nodejs + install_with_retry "sudo apt-get install -y nodejs" || exit 1 echo "Node.js version: \$(node -v)" - # Install pnpm globally (version 8) + # 3. Install pnpm globally (version 8) npm install -g pnpm@8 echo "pnpm version: \$(pnpm -v)" ''' From b71f8a7acbef1c6255c43bcf8469304fb480efc7 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:44:51 +0200 Subject: [PATCH 34/46] Remove credentialsId from Git checkout configuration for improved security and flexibility --- Jenkins/Build.Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index f90a7480..220acfee 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -22,7 +22,7 @@ pipeline { [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] ], userRemoteConfigs: [ - [credentialsId: 'YOUR_GIT_CREDENTIALS_ID', url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed + [url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed ] ]) } From b2f5fb17d4624649175579cecfa8c7befdc57eca Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 14:46:26 +0200 Subject: [PATCH 35/46] Refactor Jenkins pipeline to remove source checkout stage and enhance apt command execution with update step --- Jenkins/Build.Jenkinsfile | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 220acfee..44bd71f3 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -4,30 +4,6 @@ pipeline { agent any stages { - // Stage 1: Checkout the code with full history (fetch-depth: 0) - stage('Source Checkout') { - steps { - // Since 'git' is confirmed to be installed on agent2 (per log 'git version 2.43.0'), - // we remove the apt-get installation command which was failing due to a lock. - - // STEP: Perform the deep clone checkout using the existing Git executable. - // NOTE: Replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID - // that has access to your repository. - checkout([ - $class: 'GitSCM', - branches: [[name: 'HEAD']], - extensions: [ - [$class: 'WipeWorkspace'], - [$class: 'CleanBeforeCheckout'], - [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] - ], - userRemoteConfigs: [ - [url: env.GIT_URL ?: ''] // Replace env.GIT_URL if needed - ] - ]) - } - } - // Stage 2: Setup Node.js v20 and install pnpm stage('Setup Environment') { steps { @@ -40,6 +16,7 @@ pipeline { CMD=\$1 ATTEMPTS=0 while [ \$ATTEMPTS -lt \$MAX_ATTEMPTS ]; do + # Run update first, then the command if sudo apt-get update && \$CMD; then return 0 # Success else From c124aa648b2ebda7371014d3ed88e095737e91fc Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 15:08:46 +0200 Subject: [PATCH 36/46] Refactor Jenkins pipeline to streamline Node.js setup and enhance SonarQube analysis stage --- Jenkins/Build.Jenkinsfile | 68 +++++++++++++-------------------------- 1 file changed, 23 insertions(+), 45 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 44bd71f3..cdea710c 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -4,44 +4,28 @@ pipeline { agent any stages { + // Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins) + stage('Source Checkout') { + steps { + echo "Workspace already populated by the initial SCM checkout. Proceeding." + // No explicit checkout needed, as the initial checkout is successful. + } + } + // Stage 2: Setup Node.js v20 and install pnpm stage('Setup Environment') { steps { + // Simplified environment setup based on previous successful execution. sh ''' - ATTEMPTS=0 - MAX_ATTEMPTS=5 - - # Function to robustly run apt commands with retries in case of lock conflict - install_with_retry() { - CMD=\$1 - ATTEMPTS=0 - while [ \$ATTEMPTS -lt \$MAX_ATTEMPTS ]; do - # Run update first, then the command - if sudo apt-get update && \$CMD; then - return 0 # Success - else - ATTEMPTS=\$((ATTEMPTS + 1)) - if [ \$ATTEMPTS -lt \$MAX_ATTEMPTS ]; then - echo "Apt lock detected or command failed. Retrying in 5 seconds (Attempt \$ATTEMPTS of \$MAX_ATTEMPTS)..." - sleep 5 - fi - fi - done - echo "Failed to execute apt command after \$MAX_ATTEMPTS attempts." - return 1 # Failure - } - - # 1. Install curl (required for NodeSource script) - install_with_retry "sudo apt-get install -y curl" || exit 1 - - # 2. Install Node.js v20 (closest matching the specified version '20.17.0') - # This step uses curl (installed above) and needs its own apt-get execution. + # 1. Install Node.js v20 (closest matching the specified version '20.17.0') + # We assume 'curl' is available and installation proceeds without lock conflicts now. + echo "Setting up Node.js v20..." curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - - install_with_retry "sudo apt-get install -y nodejs" || exit 1 + sudo apt-get install -y nodejs echo "Node.js version: \$(node -v)" - # 3. Install pnpm globally (version 8) + # 2. Install pnpm globally (version 8) npm install -g pnpm@8 echo "pnpm version: \$(pnpm -v)" ''' @@ -56,7 +40,7 @@ pipeline { } } - // Stage 4: Retrieve secrets from Vault and run SonarQube analysis + // Stage 4: Run SonarQube analysis using the Jenkins plugin's environment. stage('SonarQube Analysis') { steps { script { @@ -64,25 +48,19 @@ pipeline { def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() echo "Commit SHA (short) is: ${commitShaShort}" - // 2. Retrieve secrets from HashiCorp Vault using the dedicated plugin binding. - withCredentials([ - // Requires the Jenkins HashiCorp Vault Plugin - [$class: 'VaultSecretCredentialsBinding', - vaultSecrets: [ - // Map key 'SONAR_TOKEN' from Vault path 'postiz/data/ci/sonar' to Jenkins environment variable 'SONAR_TOKEN' - [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_TOKEN', envVar: 'SONAR_TOKEN'], - // Map key 'SONAR_HOST_URL' from Vault path 'postiz/data/ci/sonar', to Jenkins environment variable 'SONAR_HOST_URL'] - [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_HOST_URL', envVar: 'SONAR_HOST_URL'] - ]] - ]) { + // 2. Use withSonarQubeEnv to set up the environment and PATH for sonar-scanner. + // IMPORTANT: Replace 'YourSonarServerName' with the name you configured + // for your SonarQube server instance in Jenkins (Manage Jenkins -> Configure System). + withSonarQubeEnv(installationName: 'YourSonarServerName') { // 3. Execute sonar-scanner CLI sh """ echo "Starting SonarQube Analysis for project version: ${commitShaShort}" sonar-scanner \\ -Dsonar.projectVersion=${commitShaShort} \\ - -Dsonar.token=\${SONAR_TOKEN} \\ - -Dsonar.host.url=\${SONAR_HOST_URL} - # Add other analysis properties here if needed (e.g., -Dsonar.projectKey=...) + -Dsonar.sources=. \\ + -Dsonar.host.url=\${SONAR_HOST_URL} \\ + -Dsonar.token=\${SONAR_TOKEN} + # Add -Dsonar.projectKey=YourKeyHere if not defined in sonar-project.properties """ } } From 77b91d4d7c2d5045549b9a4381005e5fa2ccf942 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 15:16:34 +0200 Subject: [PATCH 37/46] Update SonarQube environment configuration to use 'SonarQube-Server' and change token variable to 'SONAR_AUTH_TOKEN' --- Jenkins/Build.Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index cdea710c..0328b5db 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -51,7 +51,7 @@ pipeline { // 2. Use withSonarQubeEnv to set up the environment and PATH for sonar-scanner. // IMPORTANT: Replace 'YourSonarServerName' with the name you configured // for your SonarQube server instance in Jenkins (Manage Jenkins -> Configure System). - withSonarQubeEnv(installationName: 'YourSonarServerName') { + withSonarQubeEnv(installationName: 'SonarQube-Server') { // 3. Execute sonar-scanner CLI sh """ echo "Starting SonarQube Analysis for project version: ${commitShaShort}" @@ -59,7 +59,7 @@ pipeline { -Dsonar.projectVersion=${commitShaShort} \\ -Dsonar.sources=. \\ -Dsonar.host.url=\${SONAR_HOST_URL} \\ - -Dsonar.token=\${SONAR_TOKEN} + -Dsonar.token=\${SONAR_AUTH_TOKEN} # Add -Dsonar.projectKey=YourKeyHere if not defined in sonar-project.properties """ } From 29384eebab3c1abd8073cdb941368a854c4154c1 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 15:23:21 +0200 Subject: [PATCH 38/46] Refactor Jenkins pipeline to enhance SonarQube analysis stage with manual scanner installation and improved environment variable handling --- Jenkins/Build.Jenkinsfile | 64 ++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 0328b5db..0e6f79f7 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -3,29 +3,42 @@ pipeline { // Defines the execution environment. Using 'agent any' to ensure an agent is available. agent any + // Define environment variables for fixed values and credentials needed later + environment { + // Sonar Host URL taken from your previous successful log injection + SONAR_HOST_URL = 'https://sonarqube.ennogelhaus.de/' + // IMPORTANT: Replace this with the ID of your Jenkins Secret Text credential containing the Sonar Token + SONAR_TOKEN_CREDENTIAL_ID = 'YOUR_SECRET_TOKEN_ID' + // This will hold the path to the downloaded scanner directory later + SCANNER_HOME = '' + } + stages { // Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins) stage('Source Checkout') { steps { echo "Workspace already populated by the initial SCM checkout. Proceeding." - // No explicit checkout needed, as the initial checkout is successful. } } // Stage 2: Setup Node.js v20 and install pnpm stage('Setup Environment') { steps { - // Simplified environment setup based on previous successful execution. + // Ensure required utilities are installed (curl, unzip, which is needed for scanner extraction) + sh ''' + echo "Ensuring required utilities are installed (curl, unzip)..." + sudo apt-get update + sudo apt-get install -y curl unzip + ''' + + // Install Node.js v20 and pnpm sh ''' - # 1. Install Node.js v20 (closest matching the specified version '20.17.0') - # We assume 'curl' is available and installation proceeds without lock conflicts now. echo "Setting up Node.js v20..." curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs - echo "Node.js version: \$(node -v)" - # 2. Install pnpm globally (version 8) + echo "Installing pnpm globally..." npm install -g pnpm@8 echo "pnpm version: \$(pnpm -v)" ''' @@ -40,27 +53,44 @@ pipeline { } } - // Stage 4: Run SonarQube analysis using the Jenkins plugin's environment. + // Stage 4: Manual SonarQube Analysis (Download Scanner + Execute) stage('SonarQube Analysis') { steps { script { // 1. Get the short 8-character commit SHA for project versioning def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() echo "Commit SHA (short) is: ${commitShaShort}" - - // 2. Use withSonarQubeEnv to set up the environment and PATH for sonar-scanner. - // IMPORTANT: Replace 'YourSonarServerName' with the name you configured - // for your SonarQube server instance in Jenkins (Manage Jenkins -> Configure System). - withSonarQubeEnv(installationName: 'SonarQube-Server') { - // 3. Execute sonar-scanner CLI + + // --- Manual Scanner Installation --- + // Download the latest scanner CLI package and extract it into the workspace + sh """ + echo "Downloading Sonar Scanner CLI..." + # Using a stable, public download link for the scanner CLI + curl -sS -o sonar-scanner.zip \ + "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip" + + unzip -q sonar-scanner.zip -d . + + # Find the extracted directory name (e.g., sonar-scanner-4.7.0.2747) + def scannerDir = sh(returnStdout: true, script: 'find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1').trim() + + echo "Scanner extracted to: \${scannerDir}" + env.SCANNER_HOME = "\${scannerDir}" + """ + + // 2. Use withCredentials to inject the token securely + // The token is temporarily available as SONAR_TOKEN_VAR inside this block. + withCredentials([string(credentialsId: env.SONAR_TOKEN_CREDENTIAL_ID, variable: 'SONAR_TOKEN_VAR')]) { + // 3. Execute sonar-scanner CLI using the direct path sh """ echo "Starting SonarQube Analysis for project version: ${commitShaShort}" - sonar-scanner \\ + + \${SCANNER_HOME}/bin/sonar-scanner \\ -Dsonar.projectVersion=${commitShaShort} \\ -Dsonar.sources=. \\ - -Dsonar.host.url=\${SONAR_HOST_URL} \\ - -Dsonar.token=\${SONAR_AUTH_TOKEN} - # Add -Dsonar.projectKey=YourKeyHere if not defined in sonar-project.properties + -Dsonar.host.url=${env.SONAR_HOST_URL} \\ + -Dsonar.token=\${env.SONAR_AUTH_TOKEN} + # Replace 'YOUR_PROJECT_KEY_HERE' with the unique key for your project in SonarQube. """ } } From 022cc3c32f8002883a75aac47acf7fc439700cb6 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 15:27:01 +0200 Subject: [PATCH 39/46] Refactor Jenkins pipeline to streamline environment setup by removing unnecessary environment variables and enhancing SonarQube analysis with manual scanner installation --- Jenkins/Build.Jenkinsfile | 88 +++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index 0e6f79f7..ff637371 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -3,16 +3,6 @@ pipeline { // Defines the execution environment. Using 'agent any' to ensure an agent is available. agent any - // Define environment variables for fixed values and credentials needed later - environment { - // Sonar Host URL taken from your previous successful log injection - SONAR_HOST_URL = 'https://sonarqube.ennogelhaus.de/' - // IMPORTANT: Replace this with the ID of your Jenkins Secret Text credential containing the Sonar Token - SONAR_TOKEN_CREDENTIAL_ID = 'YOUR_SECRET_TOKEN_ID' - // This will hold the path to the downloaded scanner directory later - SCANNER_HOME = '' - } - stages { // Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins) stage('Source Checkout') { @@ -21,27 +11,45 @@ pipeline { } } - // Stage 2: Setup Node.js v20 and install pnpm - stage('Setup Environment') { + // Stage 2: Setup Node.js v20, install pnpm, and MANUALLY install Sonar Scanner + stage('Setup Environment and Tools') { steps { - // Ensure required utilities are installed (curl, unzip, which is needed for scanner extraction) sh ''' - echo "Ensuring required utilities are installed (curl, unzip)..." + echo "Ensuring required utilities and Node.js are installed..." sudo apt-get update - sudo apt-get install -y curl unzip - ''' - - // Install Node.js v20 and pnpm - sh ''' - echo "Setting up Node.js v20..." + sudo apt-get install -y curl unzip nodejs + + # 1. Install Node.js v20 + # We are using the package manager approach which we fixed earlier curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs + echo "Node.js version: \$(node -v)" - echo "Installing pnpm globally..." + # 2. Install pnpm globally (version 8) npm install -g pnpm@8 echo "pnpm version: \$(pnpm -v)" ''' + + // --- MANUALLY INSTALL THE SONAR SCANNER CLI --- + // We do this to work around the path injection failure of the SonarQube plugin. + script { + sh """ + echo "Manually downloading and installing Sonar Scanner CLI..." + # Download the stable scanner CLI package + curl -sS -o sonar-scanner.zip \ + "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip" + + unzip -q sonar-scanner.zip -d . + + # Find the extracted directory name + def scannerDir = sh(returnStdout: true, script: 'find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1').trim() + + # Add the scanner's bin directory to the execution PATH for subsequent steps + echo "Adding ${scannerDir}/bin to PATH" + env.PATH = "\$PATH:\$PWD/${scannerDir}/bin" + """ + } } } @@ -53,44 +61,24 @@ pipeline { } } - // Stage 4: Manual SonarQube Analysis (Download Scanner + Execute) + // Stage 4: Run SonarQube analysis using the plugin's variables but the manually added executable path. stage('SonarQube Analysis') { steps { script { // 1. Get the short 8-character commit SHA for project versioning def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() echo "Commit SHA (short) is: ${commitShaShort}" - - // --- Manual Scanner Installation --- - // Download the latest scanner CLI package and extract it into the workspace - sh """ - echo "Downloading Sonar Scanner CLI..." - # Using a stable, public download link for the scanner CLI - curl -sS -o sonar-scanner.zip \ - "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip" - - unzip -q sonar-scanner.zip -d . - - # Find the extracted directory name (e.g., sonar-scanner-4.7.0.2747) - def scannerDir = sh(returnStdout: true, script: 'find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1').trim() - - echo "Scanner extracted to: \${scannerDir}" - env.SCANNER_HOME = "\${scannerDir}" - """ - - // 2. Use withCredentials to inject the token securely - // The token is temporarily available as SONAR_TOKEN_VAR inside this block. - withCredentials([string(credentialsId: env.SONAR_TOKEN_CREDENTIAL_ID, variable: 'SONAR_TOKEN_VAR')]) { - // 3. Execute sonar-scanner CLI using the direct path + + // 2. Use withSonarQubeEnv to set up the secure variables (which worked last time) + // IMPORTANT: Replace 'YOUR_SONAR_INSTALLATION_NAME' + withSonarQubeEnv(installationName: 'SonarQube-Server') { + // 3. Execute sonar-scanner CLI (which is now in PATH) sh """ echo "Starting SonarQube Analysis for project version: ${commitShaShort}" - - \${SCANNER_HOME}/bin/sonar-scanner \\ + # SONAR_HOST_URL and SONAR_TOKEN are injected by withSonarQubeEnv + sonar-scanner \\ -Dsonar.projectVersion=${commitShaShort} \\ - -Dsonar.sources=. \\ - -Dsonar.host.url=${env.SONAR_HOST_URL} \\ - -Dsonar.token=\${env.SONAR_AUTH_TOKEN} - # Replace 'YOUR_PROJECT_KEY_HERE' with the unique key for your project in SonarQube. + -Dsonar.sources=. """ } } From 22dac4413c75cd6e13f77713e27dc834069bd69a Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 15:29:26 +0200 Subject: [PATCH 40/46] Refactor Jenkins pipeline to enhance SonarQube analysis by setting the global SONAR_SCANNER_PATH and improving scanner installation process --- Jenkins/Build.Jenkinsfile | 43 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index ff637371..ebc3c0cf 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -3,6 +3,11 @@ pipeline { // Defines the execution environment. Using 'agent any' to ensure an agent is available. agent any + // Global environment variable to store the path to the manually installed scanner. + environment { + SONAR_SCANNER_PATH = '' + } + stages { // Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins) stage('Source Checkout') { @@ -20,10 +25,8 @@ pipeline { sudo apt-get install -y curl unzip nodejs # 1. Install Node.js v20 - # We are using the package manager approach which we fixed earlier curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs - echo "Node.js version: \$(node -v)" # 2. Install pnpm globally (version 8) @@ -31,11 +34,11 @@ pipeline { echo "pnpm version: \$(pnpm -v)" ''' - // --- MANUALLY INSTALL THE SONAR SCANNER CLI --- - // We do this to work around the path injection failure of the SonarQube plugin. + // --- MANUALLY INSTALL THE SONAR SCANNER CLI (FIXED GROOVY SCOPE) --- script { sh """ echo "Manually downloading and installing Sonar Scanner CLI..." + # Download the stable scanner CLI package curl -sS -o sonar-scanner.zip \ "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip" @@ -43,12 +46,20 @@ pipeline { unzip -q sonar-scanner.zip -d . # Find the extracted directory name - def scannerDir = sh(returnStdout: true, script: 'find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1').trim() + def scannerDir = \$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1) - # Add the scanner's bin directory to the execution PATH for subsequent steps - echo "Adding ${scannerDir}/bin to PATH" - env.PATH = "\$PATH:\$PWD/${scannerDir}/bin" + echo "Scanner extracted to: \${scannerDir}" + + # Set the global environment variable (SONAR_SCANNER_PATH) + // This allows us to run the scanner by full path in the next stage + echo "SONAR_SCANNER_PATH=\${scannerDir}/bin" > .scanner_path.env """ + // Load the environment variable set by the shell script + // This is the correct way to pass shell variables back to Groovy/Jenkins environment + def scannerPath = readProperties file: '.scanner_path.env' + env.SONAR_SCANNER_PATH = "${env.WORKSPACE}/${scannerPath.SONAR_SCANNER_PATH}" + + echo "Global Sonar Path set to: ${env.SONAR_SCANNER_PATH}" } } } @@ -61,7 +72,7 @@ pipeline { } } - // Stage 4: Run SonarQube analysis using the plugin's variables but the manually added executable path. + // Stage 4: Run SonarQube analysis using the plugin's variables and the manual path. stage('SonarQube Analysis') { steps { script { @@ -69,16 +80,20 @@ pipeline { def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() echo "Commit SHA (short) is: ${commitShaShort}" - // 2. Use withSonarQubeEnv to set up the secure variables (which worked last time) - // IMPORTANT: Replace 'YOUR_SONAR_INSTALLATION_NAME' + // 2. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN) + // The 'SonarQube-Server' name is used as per your previous log. withSonarQubeEnv(installationName: 'SonarQube-Server') { - // 3. Execute sonar-scanner CLI (which is now in PATH) + // 3. Execute the scanner using the manually determined full path. + // We rely on the sonar-project.properties file for the project key. sh """ echo "Starting SonarQube Analysis for project version: ${commitShaShort}" - # SONAR_HOST_URL and SONAR_TOKEN are injected by withSonarQubeEnv - sonar-scanner \\ + + \${SONAR_SCANNER_PATH}/sonar-scanner \\ -Dsonar.projectVersion=${commitShaShort} \\ -Dsonar.sources=. + + # SONAR_HOST_URL and SONAR_TOKEN are automatically passed as environment variables + # by the withSonarQubeEnv block. """ } } From 6ef1543dcd9c8de9b314b956aab57c9bafc1a906 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 15:56:16 +0200 Subject: [PATCH 41/46] Refactor Jenkins pipeline to remove global environment variable for Sonar Scanner and streamline installation process within the analysis stage --- Jenkins/Build.Jenkinsfile | 71 +++++++++++++---------------- Jenkins/BuildPR.Jenkinsfile | 89 ++++++++++++++++++------------------- 2 files changed, 76 insertions(+), 84 deletions(-) diff --git a/Jenkins/Build.Jenkinsfile b/Jenkins/Build.Jenkinsfile index ebc3c0cf..886ade0a 100644 --- a/Jenkins/Build.Jenkinsfile +++ b/Jenkins/Build.Jenkinsfile @@ -3,10 +3,7 @@ pipeline { // Defines the execution environment. Using 'agent any' to ensure an agent is available. agent any - // Global environment variable to store the path to the manually installed scanner. - environment { - SONAR_SCANNER_PATH = '' - } + // Global environment block removed to prevent Groovy scoping issues with manual path calculation. stages { // Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins) @@ -16,7 +13,7 @@ pipeline { } } - // Stage 2: Setup Node.js v20, install pnpm, and MANUALLY install Sonar Scanner + // Stage 2: Setup Node.js v20 and install pnpm stage('Setup Environment and Tools') { steps { sh ''' @@ -33,34 +30,6 @@ pipeline { npm install -g pnpm@8 echo "pnpm version: \$(pnpm -v)" ''' - - // --- MANUALLY INSTALL THE SONAR SCANNER CLI (FIXED GROOVY SCOPE) --- - script { - sh """ - echo "Manually downloading and installing Sonar Scanner CLI..." - - # Download the stable scanner CLI package - curl -sS -o sonar-scanner.zip \ - "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip" - - unzip -q sonar-scanner.zip -d . - - # Find the extracted directory name - def scannerDir = \$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1) - - echo "Scanner extracted to: \${scannerDir}" - - # Set the global environment variable (SONAR_SCANNER_PATH) - // This allows us to run the scanner by full path in the next stage - echo "SONAR_SCANNER_PATH=\${scannerDir}/bin" > .scanner_path.env - """ - // Load the environment variable set by the shell script - // This is the correct way to pass shell variables back to Groovy/Jenkins environment - def scannerPath = readProperties file: '.scanner_path.env' - env.SONAR_SCANNER_PATH = "${env.WORKSPACE}/${scannerPath.SONAR_SCANNER_PATH}" - - echo "Global Sonar Path set to: ${env.SONAR_SCANNER_PATH}" - } } } @@ -72,7 +41,7 @@ pipeline { } } - // Stage 4: Run SonarQube analysis using the plugin's variables and the manual path. + // Stage 4: Run SonarQube analysis: Install scanner, get version, and execute. stage('SonarQube Analysis') { steps { script { @@ -80,15 +49,39 @@ pipeline { def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() echo "Commit SHA (short) is: ${commitShaShort}" - // 2. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN) - // The 'SonarQube-Server' name is used as per your previous log. + // --- 2. MANUALLY INSTALL THE SONAR SCANNER CLI LOCALLY IN THIS STAGE --- + sh """ + echo "Manually downloading and installing Sonar Scanner CLI..." + + # Download the stable scanner CLI package + curl -sS -o sonar-scanner.zip \ + "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip" + + # Added -o flag to force overwrite and prevent interactive prompt failure + unzip -o -q sonar-scanner.zip -d . + """ + + // 3. Find the extracted directory name and capture the full absolute bin path in Groovy + // This is defined locally and used directly, avoiding environment variable issues. + def scannerBinPath = sh( + returnStdout: true, + script: ''' + SCANNER_DIR=$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1) + # Get the full absolute path to the executable file + echo \$(pwd)/\${SCANNER_DIR}/bin/sonar-scanner + ''' + ).trim() + + echo "Scanner executable path captured: ${scannerBinPath}" + + // 4. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN) withSonarQubeEnv(installationName: 'SonarQube-Server') { - // 3. Execute the scanner using the manually determined full path. - // We rely on the sonar-project.properties file for the project key. + // 5. Execute the scanner using the Groovy variable directly. sh """ echo "Starting SonarQube Analysis for project version: ${commitShaShort}" - \${SONAR_SCANNER_PATH}/sonar-scanner \\ + # Execute the full, absolute path captured in the Groovy variable. + '${scannerBinPath}' \\ -Dsonar.projectVersion=${commitShaShort} \\ -Dsonar.sources=. diff --git a/Jenkins/BuildPR.Jenkinsfile b/Jenkins/BuildPR.Jenkinsfile index 3840b726..49237fc8 100644 --- a/Jenkins/BuildPR.Jenkinsfile +++ b/Jenkins/BuildPR.Jenkinsfile @@ -1,54 +1,38 @@ // Declarative Pipeline for building Node.js application and running SonarQube analysis for a Pull Request. pipeline { - // Defines the execution environment. Replace 'linux-agent' with your specific agent label. + // Defines the execution environment. Using 'agent any' to ensure an agent is available. agent any - - // Environment variables that hold PR details (set automatically by Jenkins SCM plugins like Git/GitHub Branch Source) + + // Environment variables that hold PR details, provided by Jenkins Multibranch setup. environment { - // These variables are provided by Jenkins (e.g., in a Multibranch Pipeline setup) - // CHANGE_ID corresponds to ${{ github.event.pull_request.number }} - // CHANGE_BRANCH corresponds to ${{ github.event.pull_request.head.ref }} - // CHANGE_TARGET corresponds to ${{ github.event.pull_request.base.ref }} + // These variables are typically provided by Jenkins (e.g., in a Multibranch Pipeline setup) PR_KEY = env.CHANGE_ID PR_BRANCH = env.CHANGE_BRANCH PR_BASE = env.CHANGE_TARGET } stages { - // Stage 1: Checkout the code with full history (fetch-depth: 0) + // Stage 1: Checkout the code (Relies on the initial SCM checkout done by Jenkins) stage('Source Checkout') { steps { - script { - // This performs a deep clone (fetch-depth: 0) - // NOTE: You must replace 'YOUR_GIT_CREDENTIALS_ID' with the actual Jenkins credential ID - // that has access to your repository. - checkout([ - $class: 'GitSCM', - branches: [[name: 'HEAD']], - extensions: [ - [$class: 'WipeWorkspace'], - [$class: 'CleanBeforeCheckout'], - [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false] - ], - userRemoteConfigs: [ - [url: env.GIT_URL ?: ''] - ] - ]) - } + echo "Workspace already populated by the initial SCM checkout. Proceeding." } } - // Stage 2: Setup Node.js v20 and install pnpm - stage('Setup Environment') { + // Stage 2: Setup Node.js v20, install pnpm, and install required tools (curl, unzip) + stage('Setup Environment and Tools') { steps { sh ''' - # Install Node.js v20 (closest matching the specified version '20.17.0') + echo "Ensuring required utilities and Node.js are installed..." + sudo apt-get update + sudo apt-get install -y curl unzip nodejs + + # 1. Install Node.js v20 (closest matching the specified version '20.17.0') curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs - echo "Node.js version: \$(node -v)" - # Install pnpm globally (version 8) + # 2. Install pnpm globally (version 8) npm install -g pnpm@8 echo "pnpm version: \$(pnpm -v)" ''' @@ -63,7 +47,7 @@ pipeline { } } - // Stage 4: Retrieve secrets from Vault and run SonarQube PR analysis + // Stage 4: Run SonarQube PR analysis: Install scanner locally, get version, and execute. stage('SonarQube Pull Request Analysis') { steps { script { @@ -71,26 +55,41 @@ pipeline { def commitShaShort = sh(returnStdout: true, script: 'git rev-parse --short=8 HEAD').trim() echo "Commit SHA (short) is: ${commitShaShort}" - // 2. Retrieve secrets from HashiCorp Vault using the dedicated plugin binding. - withCredentials([ - // Requires the Jenkins HashiCorp Vault Plugin - [$class: 'VaultSecretCredentialsBinding', - vaultSecrets: [ - [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_TOKEN', envVar: 'SONAR_TOKEN'], - [$class: 'VaultSecret', secretPath: 'postiz/data/ci/sonar', secretKey: 'SONAR_HOST_URL', envVar: 'SONAR_HOST_URL'] - ]] - ]) { - // 3. Execute sonar-scanner CLI with Pull Request parameters + // --- 2. MANUALLY INSTALL THE SONAR SCANNER CLI LOCALLY --- + sh """ + echo "Manually downloading and installing Sonar Scanner CLI..." + curl -sS -o sonar-scanner.zip \ + "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip" + unzip -o -q sonar-scanner.zip -d . + """ + + // 3. Find the extracted directory name and capture the full absolute executable path. + def scannerBinPath = sh( + returnStdout: true, + script: ''' + SCANNER_DIR=$(find . -maxdepth 1 -type d -name "sonar-scanner*" | head -n 1) + # Get the full absolute path to the executable file + echo \$(pwd)/\${SCANNER_DIR}/bin/sonar-scanner + ''' + ).trim() + + echo "Scanner executable path captured: ${scannerBinPath}" + + // 4. Use withSonarQubeEnv to set up the secure variables (HOST and TOKEN) + withSonarQubeEnv(installationName: 'SonarQube-Server') { + // 5. Execute the scanner using the Groovy variable directly with PR parameters. sh """ echo "Starting SonarQube Pull Request Analysis for PR #${PR_KEY}" - sonar-scanner \\ + + '${scannerBinPath}' \\ -Dsonar.projectVersion=${commitShaShort} \\ - -Dsonar.token=\${SONAR_TOKEN} \\ - -Dsonar.host.url=\${SONAR_HOST_URL} \\ + -Dsonar.sources=. \\ -Dsonar.pullrequest.key=${PR_KEY} \\ -Dsonar.pullrequest.branch=${PR_BRANCH} \\ -Dsonar.pullrequest.base=${PR_BASE} - # Add other analysis properties here if needed (e.g., -Dsonar.projectKey=...) + + # SONAR_HOST_URL and SONAR_TOKEN are automatically passed as environment variables + # by the withSonarQubeEnv block. """ } } From 826f8031747d185eeaa4dff729cc6441c5a95a31 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Fri, 3 Oct 2025 16:04:18 +0200 Subject: [PATCH 42/46] Fix quoting of environment variables in Jenkins pipeline to resolve compilation errors --- Jenkins/BuildPR.Jenkinsfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Jenkins/BuildPR.Jenkinsfile b/Jenkins/BuildPR.Jenkinsfile index 49237fc8..6e279b0e 100644 --- a/Jenkins/BuildPR.Jenkinsfile +++ b/Jenkins/BuildPR.Jenkinsfile @@ -5,10 +5,11 @@ pipeline { // Environment variables that hold PR details, provided by Jenkins Multibranch setup. environment { - // These variables are typically provided by Jenkins (e.g., in a Multibranch Pipeline setup) - PR_KEY = env.CHANGE_ID - PR_BRANCH = env.CHANGE_BRANCH - PR_BASE = env.CHANGE_TARGET + // FIX: Environment variables must be quoted or wrapped in a function call. + // We quote the 'env.CHANGE_ID' reference to fix the compilation error. + PR_KEY = "${env.CHANGE_ID}" + PR_BRANCH = "${env.CHANGE_BRANCH}" + PR_BASE = "${env.CHANGE_TARGET}" } stages { From df47e9f5edad1e2836f094c92fe46da75eda5a20 Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Sat, 4 Oct 2025 00:07:31 +0200 Subject: [PATCH 43/46] Fix Sentry sample rates for production environment --- .../src/sentry/initialize.sentry.client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts b/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts index 549c250c..ade3cc82 100644 --- a/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts +++ b/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts @@ -16,8 +16,8 @@ export const initializeSentryClient = (environment: string, dsn: string) => autoInject: false, }), ], - replaysSessionSampleRate: environment === 'development' ? 1.0 : 0.5, + replaysSessionSampleRate: environment == 1.0, replaysOnErrorSampleRate: 1.0, - profilesSampleRate: environment === 'development' ? 1.0 : 0.45, + profilesSampleRate: environment === 'development' ? 1.0 : 0.75, }); From 0128eb77b01fb8ea51519817075de4154e9ee76b Mon Sep 17 00:00:00 2001 From: Enno Gelhaus Date: Sat, 4 Oct 2025 00:07:47 +0200 Subject: [PATCH 44/46] Set replaysSessionSampleRate to a fixed value of 1.0 --- .../src/sentry/initialize.sentry.client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts b/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts index ade3cc82..db2010ac 100644 --- a/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts +++ b/libraries/react-shared-libraries/src/sentry/initialize.sentry.client.ts @@ -16,7 +16,7 @@ export const initializeSentryClient = (environment: string, dsn: string) => autoInject: false, }), ], - replaysSessionSampleRate: environment == 1.0, + replaysSessionSampleRate: 1.0, replaysOnErrorSampleRate: 1.0, profilesSampleRate: environment === 'development' ? 1.0 : 0.75, From 599e8952397543632e2e4c86535edcc0c145f5ff Mon Sep 17 00:00:00 2001 From: Nevo David Date: Tue, 7 Oct 2025 17:26:04 +0700 Subject: [PATCH 45/46] feat: upload from url --- .../v1/public.integrations.controller.ts | 34 +++++++++++++++++++ .../src/dtos/media/upload.dto.ts | 9 +++++ 2 files changed, 43 insertions(+) create mode 100644 libraries/nestjs-libraries/src/dtos/media/upload.dto.ts diff --git a/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts b/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts index c70b7e91..66415b75 100644 --- a/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts +++ b/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts @@ -26,6 +26,9 @@ import { } from '@gitroom/backend/services/auth/permissions/permission.exception.class'; import { VideoDto } from '@gitroom/nestjs-libraries/dtos/videos/video.dto'; import { VideoFunctionDto } from '@gitroom/nestjs-libraries/dtos/videos/video.function.dto'; +import { UploadDto } from '@gitroom/nestjs-libraries/dtos/media/upload.dto'; +import axios from 'axios'; +import { Readable } from 'stream'; @ApiTags('Public API') @Controller('/public/v1') @@ -56,6 +59,37 @@ export class PublicIntegrationsController { ); } + @Post('/upload-from-url') + async uploadFromUrl( + @GetOrgFromRequest() org: Organization, + @Body() body: UploadDto + ) { + const response = await axios.get(body.url, { + responseType: 'arraybuffer', + }); + + const buffer = Buffer.from(response.data); + + const getFile = await this.storage.uploadFile({ + buffer, + mimetype: 'image/jpeg', + size: buffer.length, + path: '', + fieldname: '', + destination: '', + stream: new Readable(), + filename: '', + originalname: '', + encoding: '', + }); + + return this._mediaService.saveFile( + org.id, + getFile.originalname, + getFile.path + ); + } + @Get('/find-slot/:id') async findSlotIntegration( @GetOrgFromRequest() org: Organization, diff --git a/libraries/nestjs-libraries/src/dtos/media/upload.dto.ts b/libraries/nestjs-libraries/src/dtos/media/upload.dto.ts new file mode 100644 index 00000000..4704c094 --- /dev/null +++ b/libraries/nestjs-libraries/src/dtos/media/upload.dto.ts @@ -0,0 +1,9 @@ +import { IsDefined, IsString, Validate } from 'class-validator'; +import { ValidUrlExtension } from '@gitroom/helpers/utils/valid.url.path'; + +export class UploadDto { + @IsString() + @IsDefined() + @Validate(ValidUrlExtension) + url: string; +} From 79de287542b51174ebf37672140fa1b017c28390 Mon Sep 17 00:00:00 2001 From: Nevo David <100117126+nevo-david@users.noreply.github.com> Date: Sat, 11 Oct 2025 13:42:55 +0700 Subject: [PATCH 46/46] Remove SonarQube badges from README Removed SonarQube badges from the README. --- README.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/README.md b/README.md index d59b6be0..91350317 100644 --- a/README.md +++ b/README.md @@ -19,21 +19,6 @@

- -

Your ultimate AI social media scheduling tool