diff --git a/.circleci/config.yml b/.circleci/config.yml index 8aaafe6..f42af42 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,122 +1,76 @@ version: 2.1 -orbs: - codecov: codecov/codecov@3 - jobs: - build2: - docker: - - image: cimg/base:stable - steps: - - run: - name: Create large dummy zip file (2MB) - command: | - mkdir -p dummy-data - dd if=/dev/urandom of=dummy-data/random.bin bs=1M count=2 - zip -r dummy-artifact222.zip dummy-data - - - store_artifacts: - path: dummy-artifact_not_exits.zip - destination: dummy-large-file - - - store_artifacts: - path: dummy-artifact222.zip - - build: - docker: - - image: cimg/node:current + inspect-gen2-large: + machine: + image: ubuntu-2404:current + resource_class: medium.gen2 steps: - - checkout - - - run: - name: Install dependencies - command: | - npm install --save-dev @babel/preset-env @babel/register - npm install - - - run: - name: Run tests and collect coverage - command: | - npx jest --coverage - sleep 5 - echo "Listing all files in the coverage directory:" - ls -R $CIRCLE_WORKING_DIRECTORY/coverage - find $CIRCLE_WORKING_DIRECTORY/coverage -type f - - - store_artifacts: - path: coverage/coverage-final.json - destination: coverage-report-json - - - store_artifacts: - path: coverage/lcov-report - destination: coverage-report-html - - - run: - name: Create large dummy zip file (2MB) - command: | - mkdir -p dummy-data - dd if=/dev/urandom of=dummy-data/random.bin bs=1M count=2 - zip -r dummy-artifact.zip dummy-data - - - store_artifacts: - path: dummy-artifact.zip - destination: dummy-large-file - - - run: - name: Create nested artifact structure with files at each level - command: | - base_path="/tmp/artifacts" - level1="$base_path/level1" - level2="$level1/level2" - level3="$level2/level3" - - mkdir -p "$level3" - - # Base64-encoded small valid PDF - pdf_base64="JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlIC9DYXRhbG9nL1BhZ2VzIDIgMCBSCj4+CmVuZG9iagogMiAwIG9iago8PC9UeXBlIC9QYWdlcy9Db3VudCAxL0tpZHMgWzMgMCBSXQo+PgplbmRvYmoKMyAwIG9iago8PC9UeXBlIC9QYWdlL1BhcmVudCAyIDAgUi9NZWRpYUJveCBbMCAwIDMwMCAxNDRdL0NvbnRlbnRzIDQgMCBSCj4+CmVuZG9iago0IDAgb2JqCjw8L0xlbmd0aCA0NAo+PnN0cmVhbQpCVC9GMTggVGYgMTAgMTAwIFRkIChIZWxsbyBmcm9tIHNhZmUgYmFzZTY0KSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZgowMDAwMDAwMDEwIDAwMDAwIG4KMDAwMDAwMDA2MCAwMDAwMCBuCjAwMDAwMDAxMTcgMDAwMDAgbgowMDAwMDAwMjIwIDAwMDAwIG4KdHJhaWxlcgo8PC9Sb290IDEgMCBSL1NpemUgNQo+PgpzdGFydHhyZWYKMzE1CiUlRU9GCg==" - - for dir in "$level1" "$level2" "$level3"; do - mkdir -p "$dir" - echo "This is a text file in $dir" > "$dir/sample.txt" - zip -j "$dir/sample.zip" "$dir/sample.txt" - echo "$pdf_base64" | base64 -d > "$dir/sample.pdf" - done - - - store_artifacts: - path: /tmp/artifacts - destination: additional-artifacts-folder - - - codecov/upload - - - setup_remote_docker - - - run: - name: Generate Dockerfile - command: | - echo "FROM alpine" > Dockerfile - echo "WORKDIR /app" >> Dockerfile - echo "COPY coverage /app/coverage" >> Dockerfile - echo "COPY dummy-artifact.zip /app/" >> Dockerfile - echo "CMD [\"ls\", \"-lhR\", \"/app\"]" >> Dockerfile - - - run: - name: Build Docker image - command: | - docker build -t $DOCKERHUB_USERNAME/circleci-artifact-demo:$CIRCLE_SHA1 . - - - run: - name: Authenticate with Docker Hub - command: | - echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin - - run: - name: Push Docker image + name: Inspect machine details command: | - docker push $DOCKERHUB_USERNAME/circleci-artifact-demo:$CIRCLE_SHA1 + set -euxo pipefail + + echo "=== Basic OS info ===" + uname -a + cat /etc/os-release || true + + echo + echo "=== CPU / memory ===" + nproc || true + lscpu || true + free -h || true + + echo + echo "=== Block devices ===" + lsblk || true + + echo + echo "=== DMI / virtualization hints ===" + sudo dmidecode -s system-manufacturer || true + sudo dmidecode -s system-product-name || true + sudo dmidecode -s bios-vendor || true + systemd-detect-virt || true + + echo + echo "=== Hypervisor / kernel messages ===" + dmesg | egrep -i 'hypervisor|kvm|xen|nitro|google|amazon|gcp|aws' | tail -50 || true + + echo + echo "=== Cloud metadata probes ===" + echo "--- AWS IMDS ---" + TOKEN=$(curl -sS -m 2 -X PUT "http://169.254.169.254/latest/api/token" \ + -H "X-aws-ec2-metadata-token-ttl-seconds: 60" || true) + if [ -n "${TOKEN:-}" ]; then + echo "AWS metadata reachable" + curl -sS -m 2 -H "X-aws-ec2-metadata-token: $TOKEN" \ + http://169.254.169.254/latest/meta-data/instance-type || true + curl -sS -m 2 -H "X-aws-ec2-metadata-token: $TOKEN" \ + http://169.254.169.254/latest/dynamic/instance-identity/document || true + else + echo "AWS metadata not reachable" + fi + + echo + echo "--- GCP metadata ---" + if curl -sS -m 2 -H "Metadata-Flavor: Google" \ + http://metadata.google.internal/computeMetadata/v1/instance/machine-type >/dev/null 2>&1; then + echo "GCP metadata reachable" + curl -sS -m 2 -H "Metadata-Flavor: Google" \ + http://metadata.google.internal/computeMetadata/v1/instance/machine-type || true + curl -sS -m 2 -H "Metadata-Flavor: Google" \ + http://metadata.google.internal/computeMetadata/v1/instance/cpu-platform || true + curl -sS -m 2 -H "Metadata-Flavor: Google" \ + http://metadata.google.internal/computeMetadata/v1/project/project-id || true + else + echo "GCP metadata not reachable" + fi + + echo + echo "=== Summary ===" + echo "resource_class=large.gen2" workflows: - version: 2.1 - build-test: + inspect: jobs: - - build - - build2 + - inspect-gen2-large diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d527cb4..3fbff82 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,20 +1,95 @@ -name: Workflow for Codecov example-javascript +name: Codecov CI with Vitest and SonarQube + on: [push, pull_request] + jobs: - run: + test: runs-on: ubuntu-latest + steps: - - name: Checkout + - name: Checkout repository uses: actions/checkout@v4 - - name: Set up Node 18 + + - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: 18 - - name: Install dependencies - run: npm install - - name: Run tests and collect coverage - run: npm run test - - name: Upload coverage to Codecov + + - name: Initialize clean package.json + run: | + npm init -y + npm install vitest@1.6.1 @vitest/coverage-v8@1.6.1 + # Optional: only install Codecov bundle plugin if you want bundle analysis: + # npm install @codecov/vite-plugin@latest + + - name: Add test & build scripts manually + run: | + jq '.scripts.test="vitest run --coverage"' package.json > tmp.json && mv tmp.json package.json + jq '.scripts.build="vite build"' package.json > tmp.json && mv tmp.json package.json + + - name: Create vitest.config.ts + run: | + echo "import { defineConfig } from 'vitest/config' + export default defineConfig({ + test: { + include: ['app/**/*.test.js'], + coverage: { + provider: 'v8', + reporters: ['text', 'json', 'html', 'lcov'], + reportDir: 'coverage' + }, + reporters: [ + 'default', + ['junit', { outputFile: 'junit.xml' }] + ] + } + })" > vitest.config.ts + + # Uncomment this block if you eventually want bundle analysis enabled again: + # + # - name: Create vite.config.js (for Codecov Bundle Analysis) + # run: | + # echo "import { defineConfig } from 'vite'; + # import { codecovVitePlugin } from '@codecov/vite-plugin'; + # export default defineConfig({ + # plugins: [ + # codecovVitePlugin({ + # enableBundleAnalysis: process.env.CODECOV_TOKEN !== undefined, + # bundleName: 'example-javascript', + # uploadToken: process.env.CODECOV_TOKEN + # }) + # ] + # })" > vite.config.js + + # - name: Build app for bundle analysis + # env: + # CODECOV_TOKEN: ${{ secrets.CODECOV_ORG_TOKEN }} + # run: npm run build + + - name: Run tests with coverage + run: npm run test || true + + - name: List coverage files (debugging) + run: ls -R coverage + + - name: Upload code coverage to Codecov uses: codecov/codecov-action@v5 env: CODECOV_TOKEN: ${{ secrets.CODECOV_ORG_TOKEN }} + + - name: Upload test results to Codecov + if: ${{ !cancelled() }} + uses: codecov/test-results-action@v1 + with: + token: ${{ secrets.CODECOV_ORG_TOKEN }} + + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v5 + with: + args: > + -Dsonar.projectKey=nofarb_example-javascript + -Dsonar.organization=nofarb + -Dsonar.verbose=true + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + \ No newline at end of file diff --git a/.github/workflows/enforce-license-compliance.yml b/.github/workflows/enforce-license-compliance.yml deleted file mode 100644 index 86be741..0000000 --- a/.github/workflows/enforce-license-compliance.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Enforce License Compliance - -on: - pull_request: - branches: [main, master] - -jobs: - enforce-license-compliance: - runs-on: ubuntu-latest - steps: - - name: 'Enforce License Compliance' - uses: getsentry/action-enforce-license-compliance@57ba820387a1a9315a46115ee276b2968da51f3d # main - with: - fossa_api_key: ${{ secrets.FOSSA_API_KEY }} diff --git a/README.md b/README.md index 6de9928..aaa07b0 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ For more information, please see the links below. - [Community Boards](https://community.codecov.io) - [Support](https://codecov.io/support) - [Documentation](https://docs.codecov.io) - + ## License [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fcodecov%2Fexample-javascript.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fcodecov%2Fexample-javascript?ref=badge_large) diff --git a/app/calculator.js b/app/core/calculator.js similarity index 100% rename from app/calculator.js rename to app/core/calculator.js diff --git a/app/calculator.test.js b/app/core/calculator.test.js similarity index 55% rename from app/calculator.test.js rename to app/core/calculator.test.js index 20869fa..53b897f 100644 --- a/app/calculator.test.js +++ b/app/core/calculator.test.js @@ -1,4 +1,4 @@ -import { expect, test } from '@jest/globals'; +import { expect, test } from 'vitest'; import { add, @@ -25,17 +25,5 @@ test('subtract function', () => { }); test('multiply function', () => { - expect(multiply(1, 2)).toBe(2.0); - expect(multiply(1.0, 2.0)).toBe(2.0); - expect(multiply(0, 2.0)).toBe(0.0); - expect(multiply(2.0, 0)).toBe(0.0); - expect(multiply(-4, 2.0)).toBe(-8.0); -}); - -test('divide function', () => { - expect(divide(1, 2)).toBe(0.5); - expect(divide(1.0, 2.0)).toBe(0.5); - expect(divide(0, 2.0)).toBe(0); - expect(divide(-4, 2.0)).toBe(-2.0); - // expect(divide(2.0, 0)).toBe('Cannot divide by 0'); + expect(multiply(1, 2)).toBe(2); }); diff --git a/app/utils/mathUtils.js b/app/utils/mathUtils.js new file mode 100644 index 0000000..fa2b139 --- /dev/null +++ b/app/utils/mathUtils.js @@ -0,0 +1,13 @@ +export function square(x) { + return x * x; + } + + export function cube(x) { + return x * x * x; + } + + export function factorial(n) { + if (n === 0) return 1; + return n * factorial(n - 1); + } + \ No newline at end of file diff --git a/app/utils/mathUtils.test.js b/app/utils/mathUtils.test.js new file mode 100644 index 0000000..1345f9b --- /dev/null +++ b/app/utils/mathUtils.test.js @@ -0,0 +1,14 @@ +import { expect, test } from 'vitest'; +import { square, cube, factorial } from './mathUtils'; + +test('square function', () => { + expect(square(2)).toBe(4); + expect(square(-3)).toBe(9); +}); + +test('cube function', () => { + expect(cube(2)).toBe(8); + expect(cube(-3)).toBe(-27); +}); + +// Intentionally leave factorial untested for now diff --git a/index.html b/index.html new file mode 100644 index 0000000..e69de29 diff --git a/main.js b/main.js new file mode 100644 index 0000000..d0d64b0 --- /dev/null +++ b/main.js @@ -0,0 +1,2 @@ +import { square } from './app/mathUtils.js'; +console.log(square(5)); diff --git a/package.json b/package.json index 99cf7ed..4bf8be1 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,13 @@ { - "name": "@codecov/example-javascript", - "version": "0.0.1", - "description": "Codecov Example Javascript", + "name": "example-javascript", + "version": "1.0.0", "scripts": { - "test": "vitest run --coverage --coverageReporters=lcov --coverageReporters=text --coverageReporters=html" - + "test": "vitest run --coverage" }, "dependencies": { - "vitest": "^3.0.0", - "codecov": "^3.8.0" + "vitest": "1.6.1" }, "devDependencies": { - "jest": "^29.0.0", - "jest-environment-jsdom": "^29.0.0", - "codecov": "^3.8.0" + "@vitest/coverage-v8": "1.6.1" } } diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..ab2a981 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,17 @@ +sonar.projectKey=nofarb_example-javascript +sonar.organization=nofarb +sonar.sources=. +sonar.language=js +sonar.sourceEncoding=UTF-8 + + +# This is the name and version displayed in the SonarCloud UI. +#sonar.projectName=example-javascript +#sonar.projectVersion=1.0 + + +# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. +#sonar.sources=. + +# Encoding of the source code. Default is default system encoding +#sonar.sourceEncoding=UTF-8 \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 8d38c43..686dd68 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,11 +1,15 @@ import { defineConfig } from 'vitest/config' +import { defineConfig } from "vite"; + export default defineConfig({ test: { + include: ['app/**/*.test.js'], coverage: { - provider: 'v8', // Use V8 as the coverage provider - reporters: ['text', 'json', 'html', 'lcov'], // Include 'html' and 'lcov' for HTML and LCOV reports - reportDir: 'coverage', // Optional: specify the directory for coverage reports - }, - }, + provider: 'v8', + reporters: ['lcov', 'text', 'json', 'html'], + reportDir: 'coverage' + } + } }) +