From 09da01accbec68caf61231a675bdc3ad669c7f94 Mon Sep 17 00:00:00 2001 From: borislavr Date: Tue, 19 May 2026 09:05:56 +0300 Subject: [PATCH 1/5] refactor: update configuration files and workflows for Docker and Helm releases --- config/linters/eslint.config.mjs | 54 +++++++++--------- workflow-templates/docker-release.yaml | 54 ++++++------------ workflow-templates/helm-charts-release.yaml | 62 ++++++++------------- 3 files changed, 67 insertions(+), 103 deletions(-) diff --git a/config/linters/eslint.config.mjs b/config/linters/eslint.config.mjs index 92b8e05..6f75d96 100644 --- a/config/linters/eslint.config.mjs +++ b/config/linters/eslint.config.mjs @@ -1,28 +1,28 @@ -// eslint.config.mjs -import js from "@eslint/js"; -import tseslint from "@typescript-eslint/eslint-plugin"; -import tsParser from "@typescript-eslint/parser"; - -export default [ - { - ignores: [ - "dist/**", - ] - }, - - js.configs.recommended, - - { - files: ["**/*.ts", "**/*.tsx"], - languageOptions: { - parser: tsParser, - }, - plugins: { - "@typescript-eslint": tseslint, - }, - rules: { - "no-undef": "warn", - "n/no-missing-import": "warn", - }, - }, +// eslint.config.mjs +import js from "@eslint/js"; +import tseslint from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; + +export default [ + { + ignores: [ + "dist/**", + ] + }, + + js.configs.recommended, + + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parser: tsParser, + }, + plugins: { + "@typescript-eslint": tseslint, + }, + rules: { + "no-undef": "warn", + "n/no-missing-import": "warn", + }, + }, ]; \ No newline at end of file diff --git a/workflow-templates/docker-release.yaml b/workflow-templates/docker-release.yaml index 7301095..863e4c0 100644 --- a/workflow-templates/docker-release.yaml +++ b/workflow-templates/docker-release.yaml @@ -8,6 +8,7 @@ # The workflow requires several configuration files: # - Docker build configuration file: `.qubership/docker-build-config.cfg` # Example: config/examples/docker.cfg +# Full description of configuration file can be found in docs https://github.com/Netcracker/qubership-workflow-hub/tree/main/actions/docker-config-resolver # - GitHub release drafter configuration file: `.github/release-drafter-config.yml` # Example: config/examples/release-drafter-config.yml @@ -27,6 +28,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + CONFIG_FILE: '.qubership/docker-build-config.cfg' + jobs: check-tag: name: "Check if tag exists" @@ -43,49 +47,27 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - load-docker-build-components: - needs: [check-tag] - name: "Load Docker Build Components Configuration" + load-config: runs-on: ubuntu-latest + permissions: + packages: read outputs: - component: ${{ steps.load_component.outputs.components }} - platforms: ${{ steps.load_component.outputs.platforms }} - env: - CONFIG_FILE: .qubership/docker-build-config.cfg + packages: ${{ steps.config.outputs.config }} steps: - - name: "Checkout code" + - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - - name: "Load Docker Configuration" - id: load_component - run: | - verify=$(cat "$GITHUB_WORKSPACE/${CONFIG_FILE}" | jq ' - def verify_structure: - .components as $components - | .platforms as $platforms - | ($components | type == "array") - and (all($components[]; has("name") and has("file") and has("context"))) - and ($platforms | type == "string"); - verify_structure - | if . then true else false end - ') - if [ ${verify} == 'true' ]; then - echo "✅ $GITHUB_WORKSPACE/${CONFIG_FILE} file is valid" - components=$(jq -c ".components" "$GITHUB_WORKSPACE/${CONFIG_FILE}") - platforms=$(jq -c ".platforms" "$GITHUB_WORKSPACE/${CONFIG_FILE}") - else - echo "❗ $GITHUB_WORKSPACE/${CONFIG_FILE} file is invalid" - echo "❗ $GITHUB_WORKSPACE/${CONFIG_FILE} file is invalid" >> $GITHUB_STEP_SUMMARY - exit 1 - fi - echo "components=${components}" >> $GITHUB_OUTPUT - echo "platforms=${platforms}" >> $GITHUB_OUTPUT + - name: Get Configuration File + uses: netcracker/qubership-workflow-hub/actions/docker-config-resolver@e64a1ee2fc2f68ab44a4ef416c27d83ce36ba8e1 #v2.2.1 + id: config + with: + file-path: "${{ env.CONFIG_FILE }}" create-tag: name: "Create Release Tag" - needs: [load-docker-build-components] + needs: [load-config] runs-on: ubuntu-latest permissions: contents: write @@ -102,7 +84,7 @@ jobs: docker-build: name: "${{ matrix.component.name }}" - needs: [load-docker-build-components, create-tag] + needs: [load-config, create-tag] permissions: contents: read packages: write @@ -110,7 +92,7 @@ jobs: strategy: fail-fast: true matrix: - component: ${{ fromJson(needs.load-docker-build-components.outputs.component) }} + component: ${{ fromJson(needs.load-config.outputs.packages) }} steps: - name: "Get version for current component" id: get-version @@ -124,7 +106,7 @@ jobs: download-artifact: false dry-run: false component: ${{ toJson(matrix.component) }} - platforms: ${{ needs.load-docker-build-components.outputs.platforms }} + platforms: ${{ matrix.component.platforms }} env: GITHUB_TOKEN: ${{ github.token }} diff --git a/workflow-templates/helm-charts-release.yaml b/workflow-templates/helm-charts-release.yaml index 8627fa0..2c6af91 100644 --- a/workflow-templates/helm-charts-release.yaml +++ b/workflow-templates/helm-charts-release.yaml @@ -12,6 +12,7 @@ # Example: config/examples/helm-charts-release-config.yaml # - Docker build configuration file: `.qubership/docker-build-config.cfg` # Example: config/examples/docker.cfg +# Full description of configuration file can be found in docs https://github.com/Netcracker/qubership-workflow-hub/tree/main/actions/docker-config-resolver # - Assets configuration file: `.qubership/assets-config.yml` # Example: config/examples/assets-config.yml # - GitHub release drafter configuration file: `.github/release-drafter-config.yml` @@ -34,6 +35,11 @@ run-name: ${{ github.repository }} Release ${{ github.event.inputs.release }} concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true + +env: + CHART_RELEASE_CONFIG_FILE: '.qubership/helm-charts-release-config.yaml' + DOCKER_CONFIG_FILE: '.qubership/docker-build-config.cfg' + jobs: check-tag: runs-on: ubuntu-latest @@ -48,43 +54,24 @@ jobs: check-tag: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + load-docker-build-components: runs-on: ubuntu-latest + permissions: + packages: read outputs: - component: ${{ steps.load_component.outputs.components }} - platforms: ${{ steps.load_component.outputs.platforms }} - env: - CONFIG_FILE: .qubership/docker-build-config.cfg + packages: ${{ steps.config.outputs.config }} steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - name: Checkout repository + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - - name: Load Docker Configuration - id: load_component - run: | - verify=$(cat "$GITHUB_WORKSPACE/${CONFIG_FILE}" | jq ' - def verify_structure: - .components as $components - | .platforms as $platforms - | ($components | type == "array") - and (all($components[]; has("name") and has("file") and has("context"))) - and ($platforms | type == "string"); - verify_structure - | if . then true else false end - ') - if [ ${verify} == 'true' ]; then - echo "✅ $GITHUB_WORKSPACE/${CONFIG_FILE} file is valid" - components=$(jq -c ".components" "$GITHUB_WORKSPACE/${CONFIG_FILE}") - platforms=$(jq -c ".platforms" "$GITHUB_WORKSPACE/${CONFIG_FILE}") - else - echo "❗ $GITHUB_WORKSPACE/${CONFIG_FILE} file is invalid" - echo "❗ $GITHUB_WORKSPACE/${CONFIG_FILE} file is invalid" >> $GITHUB_STEP_SUMMARY - exit 1 - fi - echo "components=${components}" >> $GITHUB_OUTPUT - echo "platforms=${platforms}" >> $GITHUB_OUTPUT + - name: Get Configuration File + uses: netcracker/qubership-workflow-hub/actions/docker-config-resolver@e64a1ee2fc2f68ab44a4ef416c27d83ce36ba8e1 #v2.2.1 + id: config + with: + file-path: "${{ env.DOCKER_CONFIG_FILE }}" docker-check-build: needs: [load-docker-build-components, check-tag] @@ -93,12 +80,8 @@ jobs: strategy: fail-fast: true matrix: - component: ${{ fromJson(needs.load-docker-build-components.outputs.component) }} + component: ${{ fromJson(needs.load-docker-build-components.outputs.packages) }} steps: - - name: Get version for current component - id: get-version - run: | - echo "IMAGE=${{ matrix.component.name }}" >> $GITHUB_ENV - name: Docker build uses: netcracker/qubership-workflow-hub/actions/docker-action@5a557213e92e3d22d0292330c4817c82af6704d2 #v2.1.2 with: @@ -106,8 +89,7 @@ jobs: download-artifact: false dry-run: true component: ${{ toJson(matrix.component) }} - platforms: ${{ needs.load-docker-build-components.outputs.platforms }} - tags: "${{ env.IMAGE_VERSION }}" + platforms: ${{ matrix.component.platforms }} env: GITHUB_TOKEN: ${{ github.token }} @@ -138,7 +120,7 @@ jobs: uses: netcracker/qubership-workflow-hub/actions/charts-values-update-action@5a557213e92e3d22d0292330c4817c82af6704d2 #v2.1.2 with: release-version: ${{ inputs.release }} - config-file: .qubership/helm-charts-release-config.yaml + config-file: ${{ env.CHART_RELEASE_CONFIG_FILE }} default-tag: ${{ inputs.release }} package-charts: true publish-charts: true @@ -160,7 +142,7 @@ jobs: strategy: fail-fast: true matrix: - component: ${{ fromJson(needs.load-docker-build-components.outputs.component) }} + component: ${{ fromJson(needs.load-docker-build-components.outputs.packages) }} steps: - name: Get version for current component id: get-version @@ -176,7 +158,7 @@ jobs: download-artifact: false dry-run: false component: ${{ toJson(matrix.component) }} - platforms: ${{ needs.load-docker-build-components.outputs.platforms }} + platforms: ${{ matrix.component.platforms }} tags: "${{ env.IMAGE_VERSION }},latest" env: GITHUB_TOKEN: ${{ github.token }} From 225f731c2d167bf6e5920ca2a774f254047ac0c3 Mon Sep 17 00:00:00 2001 From: borislavr Date: Tue, 19 May 2026 09:10:52 +0300 Subject: [PATCH 2/5] chore: add newline at end of eslint.config.mjs --- config/linters/eslint.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/linters/eslint.config.mjs b/config/linters/eslint.config.mjs index 6f75d96..b3ae099 100644 --- a/config/linters/eslint.config.mjs +++ b/config/linters/eslint.config.mjs @@ -25,4 +25,4 @@ export default [ "n/no-missing-import": "warn", }, }, -]; \ No newline at end of file +]; From 9957a20981bf78e53de6d304791be720760c4cbe Mon Sep 17 00:00:00 2001 From: borislavr Date: Tue, 19 May 2026 09:27:31 +0300 Subject: [PATCH 3/5] chore: update Docker configuration file path in release workflow --- workflow-templates/docker-release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflow-templates/docker-release.yaml b/workflow-templates/docker-release.yaml index ad5b898..0aabb6b 100644 --- a/workflow-templates/docker-release.yaml +++ b/workflow-templates/docker-release.yaml @@ -29,7 +29,7 @@ concurrency: cancel-in-progress: true env: - CONFIG_FILE: '.qubership/docker-build-config.cfg' + CONFIG_FILE: '.qubership/docker.cfg' jobs: check-tag: @@ -65,7 +65,7 @@ jobs: id: resolve uses: netcracker/qubership-workflow-hub/actions/docker-config-resolver@e64a1ee2fc2f68ab44a4ef416c27d83ce36ba8e1 # v2.2.1 with: - file-path: .qubership/docker.cfg + file-path: ${{ env.CONFIG_FILE }} create-tag: name: "Create Release Tag" From 8216a1a0227c71ab92cdf1ffe5808a615ffb6268 Mon Sep 17 00:00:00 2001 From: borislavr Date: Thu, 21 May 2026 12:07:24 +0300 Subject: [PATCH 4/5] fix(security): fix zizmor violations across workflow templates - lint-test-chart: pin helm/chart-testing-action to SHA; pass pull_request.base.ref through env var to prevent template injection - maven-release-v2: pin metadata-action and docker-action to SHA - sbom-to-release: move contents:write to job level; pin upload-release-assets to SHA - npm-publish: move contents/packages write to job level; replace secrets:inherit - npm-release: move contents/packages write to job level; replace secrets:inherit; add runs-on and permissions to tag job; add permissions to github-release job - automatic-pr-labeler: replace string-based bot check with sender.type - profanity-filter: replace string-based bot check with sender.type Co-Authored-By: Claude Sonnet 4.6 --- workflow-templates/automatic-pr-labeler.yaml | 2 +- workflow-templates/lint-test-chart.yaml | 10 +++++++--- workflow-templates/maven-release-v2.yaml | 4 ++-- workflow-templates/npm-publish.yaml | 9 ++++++--- workflow-templates/npm-release.yaml | 14 ++++++++++---- workflow-templates/profanity-filter.yaml | 2 +- workflow-templates/sbom-to-release.yaml | 6 ++++-- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/workflow-templates/automatic-pr-labeler.yaml b/workflow-templates/automatic-pr-labeler.yaml index c4c5b89..7fec5c0 100644 --- a/workflow-templates/automatic-pr-labeler.yaml +++ b/workflow-templates/automatic-pr-labeler.yaml @@ -20,7 +20,7 @@ permissions: jobs: assign-labels: name: "Assign Labels to PR #${{ github.event.pull_request.number }}" - if: (github.event.pull_request.merged == false) && (github.event.pull_request.user.login != 'dependabot[bot]') && (github.event.pull_request.user.login != 'github-actions[bot]') + if: (github.event.pull_request.merged == false) && (github.event.sender.type != 'Bot') permissions: pull-requests: write contents: read diff --git a/workflow-templates/lint-test-chart.yaml b/workflow-templates/lint-test-chart.yaml index 479dfa4..a90696e 100644 --- a/workflow-templates/lint-test-chart.yaml +++ b/workflow-templates/lint-test-chart.yaml @@ -47,11 +47,13 @@ jobs: check-latest: true - name: "Set up chart-testing" - uses: helm/chart-testing-action@v2.8.0 + uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0 - name: "Run chart-testing (lint) on pull_request" if: github.event_name == 'pull_request' - run: ct lint --config=${CONFIG_FILE} --debug --target-branch=${{ github.event.pull_request.base.ref }} + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + run: ct lint --config=${CONFIG_FILE} --debug --target-branch="${BASE_REF}" - name: "Run chart-testing (lint) on workflow_dispatch" if: github.event_name == 'workflow_dispatch' @@ -62,7 +64,9 @@ jobs: - name: "Run chart-testing (install) on pull_request" if: github.event_name == 'pull_request' - run: ct install --config=${CONFIG_FILE} --target-branch=${{ github.event.pull_request.base.ref }} + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + run: ct install --config=${CONFIG_FILE} --target-branch="${BASE_REF}" - name: "Run chart-testing (install) on workflow_dispatch" if: github.event_name == 'workflow_dispatch' diff --git a/workflow-templates/maven-release-v2.yaml b/workflow-templates/maven-release-v2.yaml index 06251d0..12f35ba 100644 --- a/workflow-templates/maven-release-v2.yaml +++ b/workflow-templates/maven-release-v2.yaml @@ -165,7 +165,7 @@ jobs: - name: "Prepare Docker tags" if: ${{ github.event.inputs.mark-as-latest != 'true' }} id: meta - uses: netcracker/qubership-workflow-hub/actions/metadata-action@v2.2.1 + uses: netcracker/qubership-workflow-hub/actions/metadata-action@e64a1ee2fc2f68ab44a4ef416c27d83ce36ba8e1 # v2.2.1 with: default-template: "{{major}}.{{minor}}.{{patch}},{{major}}.{{minor}},{{major}}" ref: ${{ needs.deploy.outputs.release-version }} @@ -177,7 +177,7 @@ jobs: - name: "Docker Build" id: docker_build - uses: netcracker/qubership-workflow-hub/actions/docker-action@v2.2.1 + uses: netcracker/qubership-workflow-hub/actions/docker-action@e64a1ee2fc2f68ab44a4ef416c27d83ce36ba8e1 # v2.2.1 with: ref: v${{ needs.deploy.outputs.release-version }} download-artifact: true diff --git a/workflow-templates/npm-publish.yaml b/workflow-templates/npm-publish.yaml index 597a646..3058687 100644 --- a/workflow-templates/npm-publish.yaml +++ b/workflow-templates/npm-publish.yaml @@ -41,12 +41,14 @@ on: default: 'latest' permissions: - contents: write - packages: write + contents: read jobs: npm-publish: name: "NPM Package Publish" + permissions: + contents: write + packages: write uses: Netcracker/qubership-workflow-hub/.github/workflows/re-npm-publish.yml@e64a1ee2fc2f68ab44a4ef416c27d83ce36ba8e1 #v2.2.1 with: version: ${{ github.event_name == 'workflow_dispatch' && inputs.version || '' }} @@ -57,4 +59,5 @@ jobs: dry-run: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.dry-run) }} dist-tag: ${{ github.event_name == 'workflow_dispatch' && inputs.npm-dist-tag || 'latest' }} ref: ${{ github.ref_name }} - secrets: inherit + secrets: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/workflow-templates/npm-release.yaml b/workflow-templates/npm-release.yaml index da79f18..e26ca71 100644 --- a/workflow-templates/npm-release.yaml +++ b/workflow-templates/npm-release.yaml @@ -69,8 +69,7 @@ on: default: 'latest' permissions: - contents: write - packages: write + contents: read jobs: check-tag: @@ -107,7 +106,8 @@ jobs: with: version: '' dry-run: true - secrets: inherit + secrets: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} npm-publish: name: "NPM Package Publish" @@ -123,12 +123,16 @@ jobs: dry-run: ${{ inputs.dry-run }} dist-tag: ${{ inputs.npm-dist-tag }} ref: ${{ github.ref_name }} - secrets: inherit + secrets: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} tag: name: "Create Git Tag" if: ${{ !inputs.dry-run }} needs: [npm-publish] + runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Create tag uses: netcracker/qubership-workflow-hub/actions/tag-action@e64a1ee2fc2f68ab44a4ef416c27d83ce36ba8e1 #v2.2.1 @@ -144,6 +148,8 @@ jobs: name: "Create GitHub Release" if: ${{ !inputs.dry-run }} needs: [tag] + permissions: + contents: write uses: netcracker/qubership-workflow-hub/.github/workflows/release-drafter.yml@d11baa8a4b42d1a931808c0766ee23eb344c47dd #v2.2.0 with: version: ${{ github.event.inputs.version }} diff --git a/workflow-templates/profanity-filter.yaml b/workflow-templates/profanity-filter.yaml index 194f846..77dfc5d 100644 --- a/workflow-templates/profanity-filter.yaml +++ b/workflow-templates/profanity-filter.yaml @@ -20,7 +20,7 @@ jobs: steps: - name: Scan issue or pull request for profanity # Conditionally run the step if the actor isn't a bot - if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'github-actions[bot]' }} + if: ${{ github.event.sender.type != 'Bot' }} uses: IEvangelist/profanity-filter@7d6e0c79ee3d33ae09b5ed0c6e2fa04b9c512e08 #10.0 id: profanity-filter with: diff --git a/workflow-templates/sbom-to-release.yaml b/workflow-templates/sbom-to-release.yaml index ea709cc..3887656 100644 --- a/workflow-templates/sbom-to-release.yaml +++ b/workflow-templates/sbom-to-release.yaml @@ -10,11 +10,13 @@ on: required: true default: "" permissions: - contents: write + contents: read jobs: generate-sbom: name: "Generate SBOM and Upload to Release" runs-on: ubuntu-latest + permissions: + contents: write steps: - name: "Set RELEASE_VERSION" id: set-version @@ -41,7 +43,7 @@ jobs: shell: bash - name: "Upload SBOM file to GitHub Release" - uses: AButler/upload-release-assets@v3.0 + uses: AButler/upload-release-assets@3d6774fae0ed91407dc5ae29d576b166536d1777 # v3.0 with: files: "**/${{ github.event.repository.name }}_sbom.${{ env.RELEASE_VERSION }}.json" repo-token: ${{ secrets.GITHUB_TOKEN }} From 302770f49187af2a0b19ccd9df8a1f4cdca33222 Mon Sep 17 00:00:00 2001 From: borislavr Date: Thu, 21 May 2026 12:23:49 +0300 Subject: [PATCH 5/5] chore: update biome schema version to 2.4.10 in linter configuration --- .github/linters/biome.json | 2 +- config/linters/biome.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/linters/biome.json b/.github/linters/biome.json index 644bd0a..dc4c9a5 100644 --- a/.github/linters/biome.json +++ b/.github/linters/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.3.7/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.10/schema.json", "root": false, "formatter": { "enabled": false diff --git a/config/linters/biome.json b/config/linters/biome.json index 644bd0a..dc4c9a5 100644 --- a/config/linters/biome.json +++ b/config/linters/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.3.7/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.10/schema.json", "root": false, "formatter": { "enabled": false