diff --git a/.env.example b/.env.example index a498815..005a09c 100644 --- a/.env.example +++ b/.env.example @@ -1,26 +1,24 @@ BASE_URL= API_TOKEN= -ENABLE_FINDINGS_INGESTION=true/false -# [Optioanl] +ENABLE_FINDINGS_INGESTION=true +# [Optional] # INFO, MINOR -> LOW in API Version 2 # MAJOR -> MEDIUM in API Version 2 # CRITICAL BLOCKERS -> HIGH in API Version 2 -# 0 or more values you can pass from given values FINDING_SEVERITIES=INFO,MINOR,MAJOR,CRITICAL,BLOCKER -# [Optioanl] +# [Optional] # OPEN -> OPEN in API Version 2 # CONFIRMED -> CONFIRMED' in API Version 2 # REOPENED -> FALSE_POSITIVE' in API Version 2 # RESOLVED -> ACCEPTED' in API Version 2 # CLOSED -> FIXED in API Version 2 -# 0 or more values you can pass from given values FINDING_STATUS=OPEN,CONFIRMED,REOPENED,RESOLVED,CLOSED -# [Optioanl] -#To retrieve issues created during a time span before the current time (exclusive). Accepted units are 'y' for year, 'm' for month, 'w' for week and 'd' for day. If this parameter is set, createdAfter must not be set +# [Optional] +# To retrieve issues created during a time span before the current time (exclusive). # Example value: any number -> 30 60 90 ... FINDINGS_INGEST_SINCE_DAYS= -# [Optioanl] +# [Optional] # CODE_SMELL -> MAINTAINABILITY in API Version 2 -# BUG -> RELIABILITY in API Version 2 -# VULNERABILITY: SECURITY in API Version 2 -FINDING_TYPES=CODE_SMELL,BUG,VULNERABILITY # 0 or more values you can pass from given values +# BUG -> RELIABILITY in API Version 2 +# VULNERABILITY: SECURITY in API Version 2 +FINDING_TYPES=CODE_SMELL,BUG,VULNERABILITY diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9be9e9e..4f15064 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,24 +1,22 @@ name: Build -on: [push, pull_request] +on: + pull_request: + push: + branches: + - main jobs: test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - node-version: [18.x] - os: [ubuntu-latest] - + runs-on: ubuntu-latest steps: + - name: Check out code repository source code + uses: actions/checkout@v3 + - id: setup-node name: Setup Node - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - - - name: Check out code repository source code - uses: actions/checkout@v2 + node-version: 18.x - name: Install dependencies run: yarn @@ -35,22 +33,17 @@ jobs: needs: test runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' - strategy: - fail-fast: false - matrix: - node: [18] - steps: - - name: Setup Node - uses: actions/setup-node@v1 - with: - node-version: 18.x - - name: Check out repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + # Fetch tags and describe the commit before the merge commit # to see if it's a version publish - name: Fetch tags @@ -60,6 +53,7 @@ jobs: then echo "Found version commit tag. Publishing." echo "publish=true" >> $GITHUB_ENV + echo "VERSION_NUM=`echo $(git describe --tags --abbrev=0 | sed -e "s/v//gI")`" >> $GITHUB_ENV else echo "Version commit tag not found. Not publishing." fi @@ -71,4 +65,29 @@ jobs: run: | echo "//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}" > .npmrc yarn - npm publish + yarn build + npm publish ./dist + + - name: Get Version Changelog Entry + if: env.publish == 'true' + id: changelog_reader + uses: mindsers/changelog-reader-action@v2 + with: + version: ${{ env.VERSION_NUM }} + path: ./CHANGELOG.md + continue-on-error: true + + - name: Create Release + if: env.publish == 'true' + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.changelog_reader.outputs.version }} + release_name: Release ${{ steps.changelog_reader.outputs.version }} + body: ${{ steps.changelog_reader.outputs.changes }} + prerelease: + ${{ steps.changelog_reader.outputs.status == 'prereleased' }} + draft: ${{ steps.changelog_reader.outputs.status == 'unreleased' }} + continue-on-error: true diff --git a/src/validateInvocation.ts b/src/validateInvocation.ts index 0ab957c..4eb6d0b 100644 --- a/src/validateInvocation.ts +++ b/src/validateInvocation.ts @@ -55,77 +55,11 @@ export default async function validateInvocation({ config.baseUrl = config.baseUrl.slice(0, -1); } - if (config.findingsIngestSinceDays !== undefined && isNaN(Number(config.findingsIngestSinceDays))) { - throw new IntegrationValidationError(`FINDINGS_INGEST_SINCE_DAYS must be a number if defined. Received: ${config.findingsIngestSinceDays}`); -} - const client = createSonarqubeClient(instance.config, logger); try { const systemInfo = await client.fetchSystemInfo(); config.apiVersion = getApiVersion(systemInfo); - if (config.findingSeverities) { - const findingSeverities = (config.findingSeverities as unknown as string) - .split(',') - .map((s) => s.trim()); - if (!validSeverities(findingSeverities)) { - throw new IntegrationValidationError( - 'Invalid Finding severities. Valid severities are INFO, MINOR, MAJOR, CRITICAL, BLOCKER', - ); - } - - if (config.apiVersion == APIVersion.V1) { - config.findingSeverities = findingSeverities; - } else { - const findingSeveritiesSet = new Set( - findingSeverities.map( - (findingSeverity) => FINDINGS_SEVERITIES[findingSeverity], - ), - ); - config.findingSeverities = Array.from(findingSeveritiesSet); - } - } - - if (config.findingStatus) { - const findingStatus = (config.findingStatus as unknown as string) - .split(',') - .map((s) => s.trim()); - if (!validStatuses(findingStatus)) { - throw new IntegrationValidationError( - 'Invalid Finding Status. Valid statuses are OPEN, CONFIRMED, REOPENED, RESOLVED, CLOSED', - ); - } - - if (config.apiVersion == APIVersion.V1) { - config.findingStatus = findingStatus; - } else { - const findingStatusSet = new Set( - findingStatus.map((findingStatus) => FINDING_STATUSES[findingStatus]), - ); - config.findingStatus = Array.from(findingStatusSet); - } - } - - if (config.findingTypes) { - const findingTypes = (config.findingTypes as unknown as string) - .split(',') - .map((s) => s.trim()); - if (!validTypes(findingTypes)) { - throw new IntegrationValidationError( - 'Invalid vulnerability severities. Valid types are CODE_SMELL,BUG,VULNERABILITY', - ); - } - - if (config.apiVersion == APIVersion.V1) { - config.findingTypes = findingTypes; - } else { - const findingTypesSet = new Set( - findingTypes.map((findingType) => FINDING_TYPES[findingType]), - ); - config.findingTypes = Array.from(findingTypesSet); - } - } - const resp = await client.fetchAuthenticationValidate(); if (!resp.valid) { throw new IntegrationValidationError( @@ -138,4 +72,75 @@ export default async function validateInvocation({ 'Could not verify credentials against provided Sonarqube baseUrl', ); } + + if (config.findingSeverities) { + const findingSeverities = (config.findingSeverities as unknown as string) + .split(',') + .map((s) => s.trim()); + if (!validSeverities(findingSeverities)) { + throw new IntegrationValidationError( + 'Invalid Finding severities. Valid severities are INFO, MINOR, MAJOR, CRITICAL, BLOCKER', + ); + } + + if (config.apiVersion == APIVersion.V1) { + config.findingSeverities = findingSeverities; + } else { + const findingSeveritiesSet = new Set( + findingSeverities.map( + (findingSeverity) => FINDINGS_SEVERITIES[findingSeverity], + ), + ); + config.findingSeverities = Array.from(findingSeveritiesSet); + } + } + + if (config.findingStatus) { + const findingStatus = (config.findingStatus as unknown as string) + .split(',') + .map((s) => s.trim()); + if (!validStatuses(findingStatus)) { + throw new IntegrationValidationError( + 'Invalid Finding Status. Valid statuses are OPEN, CONFIRMED, REOPENED, RESOLVED, CLOSED', + ); + } + + if (config.apiVersion == APIVersion.V1) { + config.findingStatus = findingStatus; + } else { + const findingStatusSet = new Set( + findingStatus.map((findingStatus) => FINDING_STATUSES[findingStatus]), + ); + config.findingStatus = Array.from(findingStatusSet); + } + } + + if (config.findingTypes) { + const findingTypes = (config.findingTypes as unknown as string) + .split(',') + .map((s) => s.trim()); + if (!validTypes(findingTypes)) { + throw new IntegrationValidationError( + 'Invalid vulnerability severities. Valid types are CODE_SMELL,BUG,VULNERABILITY', + ); + } + + if (config.apiVersion == APIVersion.V1) { + config.findingTypes = findingTypes; + } else { + const findingTypesSet = new Set( + findingTypes.map((findingType) => FINDING_TYPES[findingType]), + ); + config.findingTypes = Array.from(findingTypesSet); + } + } + + if ( + config.findingsIngestSinceDays !== undefined && + isNaN(Number(config.findingsIngestSinceDays)) + ) { + throw new IntegrationValidationError( + `FINDINGS_INGEST_SINCE_DAYS must be a number if defined. Received: ${config.findingsIngestSinceDays}`, + ); + } } diff --git a/test/config.ts b/test/config.ts index ac79948..c7f01f1 100644 --- a/test/config.ts +++ b/test/config.ts @@ -23,8 +23,9 @@ export function buildStepTestConfigForStep(stepId: string): StepTestConfig { baseUrl: process.env.BASE_URL || DEFAULT_BASE_URL, // Using env var to determine version since we don't want to query the system info when running a test apiVersion: (process.env.API_VERSION as APIVersion) || DEFAULT_API_VERSION, - findingsIngestSinceDays: - process.env.CREATED_IN_LAST ? + process.env.CREATED_IN_LAST : DEFAULT_CREATED_IN_LAST, + findingsIngestSinceDays: process.env.CREATED_IN_LAST + ? +process.env.CREATED_IN_LAST + : DEFAULT_CREATED_IN_LAST, }; return {