From 938ba5cc4756e06c6af195d1d132e3a059687458 Mon Sep 17 00:00:00 2001 From: Ryan Bas Date: Thu, 2 Oct 2025 07:05:26 -0600 Subject: [PATCH] chore: basic-nix-setup --- .github/actions/js-setup/action.yml | 42 +++++++++ .github/workflows/CI.yml | 82 ++++++++++------- .gitignore | 3 + javascript/flake.lock | 61 +++++++++++++ javascript/flake.nix | 57 ++++++++++++ package-lock.json | 133 ---------------------------- 6 files changed, 211 insertions(+), 167 deletions(-) create mode 100644 .github/actions/js-setup/action.yml create mode 100644 javascript/flake.lock create mode 100644 javascript/flake.nix delete mode 100644 package-lock.json diff --git a/.github/actions/js-setup/action.yml b/.github/actions/js-setup/action.yml new file mode 100644 index 00000000..fa2c284e --- /dev/null +++ b/.github/actions/js-setup/action.yml @@ -0,0 +1,42 @@ +name: 'JavaScript Setup' +description: 'Sets up the JS environment with Nix, Cachix, and cached dependencies' +inputs: + cache-playwright: + description: 'Whether to cache playwright browsers' + required: false + default: 'false' +outputs: + npm-cache-hit: + description: "Whether the npm cache was hit" + value: ${{ steps.npm-cache.outputs.cache-hit }} + playwright-cache-hit: + description: "Whether the Playwright cache was hit" + value: ${{ steps.playwright-cache.outputs.cache-hit }} +runs: + using: "composite" + steps: + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@v4 + - name: Use Cachix + uses: cachix/cachix-action@v12 + with: + name: ping-sdk-samples + - name: Cache node_modules + uses: actions/cache@v4 + id: npm-cache + with: + path: ./javascript/node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('javascript/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm- + - name: Cache Playwright browsers + if: inputs.cache-playwright == 'true' + uses: actions/cache@v4 + id: playwright-cache + with: + path: | + ~/.cache/ms-playwright + ~/Library/Caches/ms-playwright + key: ${{ runner.os }}-playwright-${{ hashFiles('javascript/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-playwright- diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 69ef61cb..97ef92a8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -5,57 +5,71 @@ on: paths: - 'javascript/**/*' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: - pr: + lint: strategy: matrix: os: [ubuntu-latest, macos-latest] - shardIndex: [1, 2, 3, 4] # Split tests into 4 shards - node: [18.19.0, 20.11.1] runs-on: ${{ matrix.os }} + timeout-minutes: 10 defaults: run: working-directory: ./javascript steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - - uses: actions/cache@v4 - id: cache - with: - path: | - node_modules - key: ${{ runner.os }}-npm-${{matrix.node}}-${{ hashFiles('package-lock.json') }} - - - run: npm ci - working-directory: ./javascript - if: steps.cache.outputs.cache-hit != 'true' + - uses: ./.github/actions/js-setup + id: setup - - name: Lint - run: npm run lint + - name: Install dependencies and Lint + run: | + nix develop --command bash -c " + set -e + if [ \"${{ steps.setup.outputs.npm-cache-hit }}\" != 'true' ]; then + npm ci + fi + npm run lint + " - - run: npx playwright install + e2e: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + shardIndex: [1, 2, 3, 4] + runs-on: ${{ matrix.os }} + timeout-minutes: 10 + defaults: + run: + working-directory: ./javascript + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/js-setup + id: setup + with: + cache-playwright: 'true' - - name: E2E Tests - Shard ${{ matrix.shardIndex }} of 4 - run: | - cd reactjs-todo && npm run e2e -- --shard=${{ matrix.shardIndex }}/4 - cd ../reactjs-todo-davinci && npm run e2e -- --shard=${{ matrix.shardIndex }}/4 - cd ../angular-todo && npm run e2e -- --shard=${{ matrix.shardIndex }}/4 - cd ../angular-todo-davinci && npm run e2e -- --shard=${{ matrix.shardIndex }}/4 + - name: Install Deps and Run E2E Tests env: REST_OAUTH_SECRET: ${{ secrets.REST_OAUTH_SECRET }} + run: | + nix develop --command bash -c " + set -e + if [ \"${{ steps.setup.outputs.npm-cache-hit }}\" != 'true' ]; then + npm ci + fi + if [ \"${{ steps.setup.outputs.playwright-cache-hit }}\" != 'true' ]; then + npx playwright install --with-deps + fi + npm run e2e -ws --if-present -- --shard=${{ matrix.shardIndex }}/4 + " - uses: actions/upload-artifact@v4 if: always() with: - name: Playwright Results - ${{ runner.os }} - ${{ matrix.node }} - Shard ${{ matrix.shardIndex }} - ${{ github.run_attempt }} + name: Playwright Results - ${{ runner.os }} - Shard ${{ matrix.shardIndex }} - ${{ github.run_attempt }} path: | - ./javascript/reactjs-todo/test-results - ./javascript/reactjs-todo/playwright-report - ./javascript/angular-todo/test-results - ./javascript/angular-todo/playwright-report - ./javascript/reactjs-todo-davinci/test-results - ./javascript/reactjs-todo-davinci/playwright-report - ./javascript/angular-todo-davinci/test-results - ./javascript/angular-todo-davinci/playwright-report + javascript/**/test-results/ + javascript/**/playwright-report/ diff --git a/.gitignore b/.gitignore index bf90ed28..f53e82c8 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,6 @@ code terminalOutput outputs/* /.idea/ +**/logs + +.direnv/* diff --git a/javascript/flake.lock b/javascript/flake.lock new file mode 100644 index 00000000..d134e37e --- /dev/null +++ b/javascript/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1759281824, + "narHash": "sha256-FIBE1qXv9TKvSNwst6FumyHwCRH3BlWDpfsnqRDCll0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5b5be50345d4113d04ba58c444348849f5585b4a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/javascript/flake.nix b/javascript/flake.nix new file mode 100644 index 00000000..d6492d63 --- /dev/null +++ b/javascript/flake.nix @@ -0,0 +1,57 @@ +{ + description = "A basic flake.nix for a Node.js project"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + devShell = pkgs.mkShell { + buildInputs = with pkgs; [ + nodejs + git + nodePackages.npm + + # Add browser dependencies for Playwright + webkitgtk + gtk3 + glib + xorg.libX11 + xorg.libXcomposite + xorg.libXdamage + xorg.libXext + xorg.libXfixes + xorg.libXrandr + xorg.libxkbcommon + xorg.libxcb + xorg.libxshmfence + nss + alsa-lib + at-spi2-atk + cups + expat + libepoxy + libdrm + libgbm + libudev0-shim + libpulseaudio + libnotify + pango + ]; + shellHook = '' + if [ ! -d "node_modules" ]; then + echo "node_modules not found. Running npm install..." + npm install + fi + echo "Nix development shell is ready." + ''; + }; + } + ); +} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index da18e34b..00000000 --- a/package-lock.json +++ /dev/null @@ -1,133 +0,0 @@ -{ - "name": "sdk-sample-apps", - "lockfileVersion": 3, - "requires": true, - "packages": { - "javascript/angular-todo": { - "extraneous": true - }, - "javascript/central-login-oidc": { - "version": "1.0.0", - "extraneous": true, - "license": "ISC", - "dependencies": { - "@forgerock/javascript-sdk": "latest" - }, - "devDependencies": { - "css-loader": "^6.8.1", - "dotenv": "^16.3.1", - "eslint": "^8.57.0", - "eslint-config-prettier": "^9.0.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-promise": "^6.1.1", - "html-webpack-plugin": "^5.5.3", - "style-loader": "^3.3.3", - "webpack": "^5.89.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.1" - } - }, - "javascript/embedded-login": { - "version": "1.0.0", - "extraneous": true, - "license": "ISC", - "dependencies": { - "@forgerock/javascript-sdk": "latest" - }, - "devDependencies": { - "css-loader": "^6.8.1", - "dotenv": "^16.3.1", - "eslint": "^8.57.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-promise": "^6.1.1", - "html-webpack-plugin": "^5.5.3", - "style-loader": "^3.3.3", - "webpack": "^5.89.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.1" - } - }, - "javascript/reactjs-todo": { - "version": "1.0.0", - "extraneous": true, - "license": "ISC", - "dependencies": { - "@forgerock/javascript-sdk": "latest", - "cookie-parser": "^1.4.5", - "cors": "^2.8.5", - "dotenv": "^10.0.0", - "express": "^4.17.1", - "pouchdb": "^7.2.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-router-dom": "^6.19.0", - "superagent": "^6.0.0", - "uuid": "^8.3.2" - }, - "devDependencies": { - "@babel/cli": "^7.14.5", - "@babel/core": "^7.14.6", - "@babel/eslint-parser": "^7.14.7", - "@babel/preset-env": "^7.14.5", - "@babel/preset-react": "^7.14.5", - "@playwright/test": "^1.42.0", - "@types/node": "^20.11.24", - "autoprefixer": "^10.2.6", - "babel-loader": "^8.2.2", - "bootstrap": "^5.0.1", - "css-loader": "^5.2.6", - "eslint": "^8.57.0", - "eslint-config-prettier": "^8.3.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsx": "^0.1.0", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-prettier": "^3.4.0", - "eslint-plugin-promise": "^6.1.1", - "eslint-plugin-react": "^7.34.1", - "eslint-plugin-react-hooks": "^4.6.0", - "local-web-server": "^4.2.1", - "mini-css-extract-plugin": "^1.6.0", - "postcss": "^8.3.5", - "postcss-loader": "^6.1.0", - "prettier": "^2.3.2", - "sass": "^1.35.1", - "sass-loader": "^12.1.0", - "shx": "^0.3.3", - "style-loader": "^2.0.0", - "webpack": "^5.72.0", - "webpack-cli": "^5.1.4" - } - }, - "javascript/todo-api": { - "version": "1.0.0", - "extraneous": true, - "license": "ISC", - "dependencies": { - "cookie-parser": "^1.4.6", - "cors": "^2.8.5", - "dotenv": "16.3.1", - "express": "4.18.2", - "pouchdb": "^7.2.2", - "superagent": "^7.0.1", - "util": "^0.12.3", - "uuid": "^8.3.2" - }, - "devDependencies": { - "eslint": "^8.57.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-promise": "^6.1.1" - }, - "engines": { - "node": ">=18" - } - } - } -}