diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index 5650724125..0000000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: "2" -checks: - method-complexity: - config: - threshold: 8 - similar-code: - config: - threshold: 200 -plugins: - fixme: - enabled: true - git-legal: - enabled: true - markdownlint: - enabled: true - scss-lint: - enabled: false -exclude_patterns: -- "config/" -- "db/" -- "dist/" -- "features/" -- "**/node_modules/" -- "script/" -- "**/spec/" -- "**/test/" -- "**/tests/" -- "**/vendor/" -- "**/*.d.ts" -- "**/__vendor/" -- "**/*_test.go" -- "website/" \ No newline at end of file diff --git a/.github/workflows/stb_tests.yml b/.github/workflows/stb_tests.yml index 31d56a30d5..485414c610 100644 --- a/.github/workflows/stb_tests.yml +++ b/.github/workflows/stb_tests.yml @@ -80,15 +80,15 @@ jobs: # The integration suite runs in real browsers (vite.config.ts defines # integration-chromium/firefox/webkit projects); CI has no browser # binaries by default. NOTE: installs all three to keep CI == local - # `npm test`; narrow to chromium if the gate gets slow. + # `bun run test`; narrow to chromium if the gate gets slow. - name: Install Playwright browsers - run: npx playwright install --with-deps + run: bun run playwright install --with-deps - name: Typecheck - run: npm run typecheck + run: bun run typecheck - name: Lint - run: npm run lint + run: bun run lint - name: Unit + integration tests - run: npm test + run: bun run test diff --git a/Makefile b/Makefile index 6a3508a415..ab72b70ac2 100644 --- a/Makefile +++ b/Makefile @@ -87,7 +87,7 @@ include version.mk # Stratos-specific build metadata and stamps — the per-repo config the # vendorable core deliberately excludes. $(_HIDE)BUILD_NODE_VERSION := $(shell node --version 2>/dev/null || echo "unknown") -$(_HIDE)BUILD_TS_VERSION := $(shell npx tsc --version 2>/dev/null | awk '{print $$2}' || echo "unknown") +$(_HIDE)BUILD_TS_VERSION := $(shell bun run tsc --version 2>/dev/null | awk '{print $$2}' || echo "unknown") $(_HIDE)BUILD_BUN_VERSION := $(shell bun --version 2>/dev/null || echo "unknown") # Lazy (=) so the backend binary's baked-in version reflects the post-bump @@ -622,7 +622,7 @@ define test.e2e $(if $(PR),--pr $(PR) )$(call _e2e_toggle,dry-run,$(DRYRUN)); \ else \ echo "Running Playwright E2E tests..."; \ - $(if $(E2E_VIDEO),E2E_VIDEO=$(E2E_VIDEO) )$(if $(E2E_SCREENSHOTS),E2E_SCREENSHOTS=$(E2E_SCREENSHOTS) )npx playwright test \ + $(if $(E2E_VIDEO),E2E_VIDEO=$(E2E_VIDEO) )$(if $(E2E_SCREENSHOTS),E2E_SCREENSHOTS=$(E2E_SCREENSHOTS) )bun run playwright test \ $(call _e2e_browsers,$(E2E_BROWSERS)) \ $(call _e2e_flag,trace,$(E2E_TRACE)) \ $(call _e2e_toggle,list,$(DRYRUN)); \ @@ -727,7 +727,7 @@ $(call register, check, coverage, $($(_HIDE)BUILD_INFO_TS)) define check.e2e $(_ensure_host_backend) @echo "Running Playwright E2E core tests..." - @$(if $(E2E_VIDEO),E2E_VIDEO=$(E2E_VIDEO) )$(if $(E2E_SCREENSHOTS),E2E_SCREENSHOTS=$(E2E_SCREENSHOTS) )npx playwright test e2e/tests/core/ \ + @$(if $(E2E_VIDEO),E2E_VIDEO=$(E2E_VIDEO) )$(if $(E2E_SCREENSHOTS),E2E_SCREENSHOTS=$(E2E_SCREENSHOTS) )bun run playwright test e2e/tests/core/ \ $(call _e2e_browsers,$(E2E_BROWSERS)) \ $(call _e2e_flag,trace,$(E2E_TRACE)) \ $(call _e2e_toggle,list,$(DRYRUN)) diff --git a/README.md b/README.md index 240094460a..71d07584f5 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Please visit our new [documentation site](https://stratos.app/). There you can d 1. [Docker](https://stratos.app/docs/deploy/all-in-one), as a single container deploying all components. 1. Configuring advanced features such as [Single Sign On](https://stratos.app/docs/advanced/sso) and Cloud Foundry '[invite to org](https://stratos.app/docs/advanced/invite-user-guide)'. 1. Guides for [developers](https://stratos.app/docs/developer/introduction). -1. How to [extend](https://stratos.app/docs/extensions/introduction) Stratos [functionality](https://stratos.app/docs/extensions/frontend) and apply a custom [theme](https://stratos.app/docs/extensions/theming). +1. How to [extend](https://stratos.app/docs/extensions/introduction) Stratos [functionality](https://stratos.app/docs/extensions/frontend) and apply a custom [theme](https://stratos.app/docs/theming-architecture). ## Developer Workflow @@ -50,87 +50,41 @@ These are taken from `engines` in `package.json` and the `go` directive in ### First-Time Setup -On a fresh checkout, run the bootstrap script **once** to initialize the development environment: - ```bash git clone https://github.com/cloudfoundry/stratos.git cd stratos - -# One-time bootstrap (builds required infrastructure) -./bootstrap -# OR -make bootstrap -# OR -bun run bootstrap - -# Install dependencies -bun install - -# Start development server -make dev-frontend +make install # bun install; its postinstall step builds the devkit ``` -**What bootstrap does:** - -1. Verifies prerequisites (Node.js, Bun, Go) -2. Builds the devkit package (required by Angular CLI) -3. Generates extension module imports -4. Creates development proxy configuration -5. Stamps `build-info.ts` so vitest can run without a full build -6. Cleans up workspace +The backend needs `src/jetstream/config.properties` with an encryption key and +a login method before its first start. The +[contributor guide](docs/contributing_guide.md#first-time-setup) has the exact +steps, including a local `admin` user and the dev TLS certificate. -**Troubleshooting:** - -- If `bun install` fails with missing files: Run `make bootstrap` first -- If builds fail with "File not found" errors: Run `make bootstrap` -- Bootstrap only needs to run once per checkout +On a fresh worktree, `./bootstrap` also stamps `build-info.ts` so the unit +tests can run before the first build. ### Development Commands -```bash -# Frontend development server (https://127.0.0.1:5440) -make dev-frontend -# OR -bun run start - -# Build for production -make build # Both frontend and backend -make build-frontend # Frontend only -make build-backend # Backend only - -# Testing -bun test # All frontend tests -bun run test-frontend:core -bun run test-frontend:cloud-foundry -bun run test-backend # Backend tests -bun run e2e # End-to-end tests - -# Linting -bun run lint -``` - -### Full Stack Development - -Run these in separate terminals: +Run every command from the repository root. `make help` lists them all. ```bash -# Terminal 1: Frontend (port 5440) -make dev-frontend - -# Terminal 2: Backend API (port 5443) -make dev-backend - -# Access at: https://127.0.0.1:5440 +# Development servers, in separate terminals +make dev backend # https://localhost:5443 +make dev frontend # https://localhost:5440 + +# Build +make build # Frontend and every backend platform +make build frontend # Frontend only +make build backend PLATFORM=linux/amd64 # One backend platform + +# Tests and checks +make test frontend # Unit tests (Vitest) +make test backend # Go tests +make test e2e # End-to-end tests (Playwright) +make check gate # Lint and unit tests, as CI runs them ``` -For more detailed information, see [CLAUDE.md](CLAUDE.md). - -## Acknowledgements - -Tested with Browserstack - -Browserstack - ## Stratos UI pre-packager This feature helps in pre-building the @@ -172,44 +126,16 @@ Note: `sgs` creates security groups the first time, upgrades do not use `sgs`. ## Packaging -Requires `node`, `go`, and `zip`. - -Build and package for all targets (linux/amd64, linux/arm64): +Build the release packages with: ```bash -bin/package +make build release # CF zip and GitHub release archives, with SHA256SUMS +make build release cf # Only the cf push-ready zip (linux/amd64) ``` -To skip the build step and package from existing artifacts: - -```bash -bin/package --skip-build -``` - -To override the version (default: from `package.json`): - -```bash -VERSION="4.8.1" bin/package -``` - -This produces per-target zips in `dist/`: - -```text -dist/stratos-cf---.zip -``` - -Deploy with: - -```bash -cf push -f dist/cf-package--/manifest.yml \ - -p dist/stratos-cf---.zip -``` - -### NOTE - -The original packaging code was based on work from the -[Orange Cloud Foundry Github Repository](https://github.com/orange-cloudfoundry/stratos-ui-cf-packager/). -Many thanks to Benjamin & Arthur, we appreciate you both! +`VERSION=` overrides the version taken from `package.json`. The CF zip +is written to `dist/stratos-cf-.zip`; see +[CF Release Build Process](docs/developer-environment.md#cf-release-build-process). ## License diff --git a/TESTING.md b/TESTING.md index e82083e77e..32aebd6d8d 100644 --- a/TESTING.md +++ b/TESTING.md @@ -155,13 +155,13 @@ Everything else stays in its existing group directory. **This ordering is enforced only by the tiered runner** (`make test e2e TIER=…` / `make test e2e GROUP=…`, which delegates to -`scripts/e2e-run.mjs`). A bare `npx playwright test` or `make test e2e` +`scripts/e2e-run.mjs`). A bare `bun run playwright test` or `make test e2e` (with no `TIER`/`GROUP` set) runs the plain Playwright test-runner directly — `dependent/` is not ordered last and can interleave with the parallel pool, reintroducing the blast-radius risk above. `make check e2e` also bypasses the tiered runner: it scopes directly to -`npx playwright test e2e/tests/core/`, so it no longer covers the +`bun run playwright test e2e/tests/core/`, so it no longer covers the endpoint lifecycle spec at all — `endpoints.spec.ts` lives in `dependent/`, outside that path. diff --git a/angular.json b/angular.json index f6be001c6b..07507b87d6 100644 --- a/angular.json +++ b/angular.json @@ -15,7 +15,7 @@ "prebuildScripts": [ { "name": "Clean symlinks", - "script": "node build/clean-symlinks.cjs", + "script": "bun build/clean-symlinks.cjs", "phase": 1, "cache": true, "cacheKey": ["src/frontend/packages/**/package.json"], @@ -24,7 +24,7 @@ }, { "name": "Store git metadata", - "script": "node build/store-git-metadata.cjs", + "script": "bun build/store-git-metadata.cjs", "phase": 1, "cache": true, "cacheKey": [".git/HEAD", ".git/refs/heads/**"], @@ -33,7 +33,7 @@ }, { "name": "Generate custom imports", - "script": "node build/extension-generator.mjs", + "script": "bun build/extension-generator.mjs", "phase": 2, "cache": true, "cacheKey": ["custom-src/**/*", "src/frontend/packages/core/custom-extensions.json"], @@ -42,7 +42,7 @@ }, { "name": "Prepare backend", - "script": "node dist-devkit/src/backend.js", + "script": "bun dist-devkit/src/backend.js", "phase": 2, "cache": true, "cacheKey": ["dist-devkit/src/backend.js", "src/jetstream/**/*.go"], diff --git a/bootstrap b/bootstrap index 9d4fba245c..6a8915baef 100755 --- a/bootstrap +++ b/bootstrap @@ -91,7 +91,7 @@ if [ ! -f "build/extension-generator.mjs" ]; then exit 1 fi -node build/extension-generator.mjs +bun build/extension-generator.mjs if [ -f "src/frontend/packages/core/src/_custom-import.module.ts" ]; then print_success "Extension module generated" @@ -107,7 +107,7 @@ if [ ! -f "build/dev-setup.cjs" ]; then exit 1 fi -node build/dev-setup.cjs +bun build/dev-setup.cjs if [ -f "proxy.conf.js" ]; then print_success "Development configuration created" diff --git a/build/ngbuild.sh b/build/ngbuild.sh index 4cf9156e1c..32e1f454bd 100755 --- a/build/ngbuild.sh +++ b/build/ngbuild.sh @@ -154,7 +154,7 @@ function build_devkit() { echo -e "${YELLOW}${BOLD}= Package: @stratosui/devkit${RESET}" echo - npm run build-devkit + bun run build-devkit rm -rf ${STRATOS}/npm_pkg/devkit cp -r ${STRATOS}/dist-devkit ${STRATOS}/npm_pkg/devkit diff --git a/bun.lock b/bun.lock index 4ca1661128..4daf4742f9 100644 --- a/bun.lock +++ b/bun.lock @@ -78,7 +78,6 @@ "adm-zip": "0.6.1", "angular-eslint": "22.5.0", "baseline-browser-mapping": "^2.11.27", - "browserstack-local": "1.5.15", "copy-webpack-plugin": "14.0.0", "eslint": "^10.11.0", "fs-extra": "11.4.1", @@ -1071,7 +1070,7 @@ "adm-zip": ["adm-zip@0.6.1", "", {}, "sha512-Xwrja8nx9e5o2N1my4DsKCeKpdrnACyr1wtbPxBDgGzKzKyE9kRtBFA8mWldI+RVlD7CBZNWY/wQ2+ydwOR6kQ=="], - "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + "agent-base": ["agent-base@9.0.0", "", {}, "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA=="], "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], @@ -1157,8 +1156,6 @@ "browserslist": ["browserslist@4.28.9", "", { "dependencies": { "baseline-browser-mapping": "^2.11.20", "caniuse-lite": "^1.0.30001810", "electron-to-chromium": "^1.5.420", "node-releases": "^2.0.54", "update-browserslist-db": "^1.3.2" }, "bin": { "browserslist": "cli.js" } }, "sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg=="], - "browserstack-local": ["browserstack-local@1.5.15", "", { "dependencies": { "agent-base": "^6.0.2", "https-proxy-agent": "^5.0.1", "is-running": "^2.1.0", "tree-kill": "^1.2.2" } }, "sha512-eiDZ5ZRHV5MiUIFlyK5H7MB0U7xHKDMQx0fPeV8KkobAUXe65mXugaRpd49dkuFhKT7TF84ZACNWE+dVra12iQ=="], - "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], @@ -1639,8 +1636,6 @@ "is-regexp": ["is-regexp@1.0.0", "", {}, "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA=="], - "is-running": ["is-running@2.1.0", "", {}, "sha512-mjJd3PujZMl7j+D395WTIO5tU5RIDBfVSRtRR4VOJou3H66E38UjbjvDGh3slJzPuolsb+yQFqwHNNdyp5jg3w=="], - "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], "is-typedarray": ["is-typedarray@1.0.0", "", {}, "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="], @@ -2247,8 +2242,6 @@ "tree-dump": ["tree-dump@1.1.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA=="], - "tree-kill": ["tree-kill@1.2.2", "", { "bin": "cli.js" }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], - "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="], "ts-graphviz": ["ts-graphviz@2.1.6", "", { "dependencies": { "@ts-graphviz/adapter": "^2.0.6", "@ts-graphviz/ast": "^2.0.7", "@ts-graphviz/common": "^2.1.5", "@ts-graphviz/core": "^2.0.7" } }, "sha512-XyLVuhBVvdJTJr2FJJV2L1pc4MwSjMhcunRVgDE9k4wbb2ee7ORYnPewxMWUav12vxyfUM686MSGsqnVRIInuw=="], @@ -2637,8 +2630,6 @@ "browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.11.21", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ=="], - "browserstack-local/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], - "buffer-image-size/@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="], "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], @@ -2703,8 +2694,6 @@ "htmlparser2/entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="], - "https-proxy-agent/agent-base": ["agent-base@9.0.0", "", {}, "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA=="], - "is-core-module/hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], "istanbul-lib-instrument/@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], diff --git a/changelog.d/0003-frontend-tests-docs.md b/changelog.d/0003-frontend-tests-docs.md new file mode 100644 index 0000000000..927ee8e366 --- /dev/null +++ b/changelog.d/0003-frontend-tests-docs.md @@ -0,0 +1,13 @@ +[BugFixes] +- `bun run e2e:dev` now targets the dev frontend on port 5440 instead of + 4200, where nothing listens. + +[Chores] +- The developer, testing, extension and Cloud Foundry deploy guides now + give the `make` and `bun` commands the repo uses today, and the + frontend tests guide lists the checks a pull request runs. +- The Makefile, the tiered E2E runner and the STB workflow run their + tools through `bun` instead of `npx` or `npm`. +- Removed the unused Code Climate configuration and script, and the + BrowserStack instructions, which stopped working with the Protractor + suite. diff --git a/docs/build-and-packaging.md b/docs/build-and-packaging.md index aca4a7c219..715376bb28 100644 --- a/docs/build-and-packaging.md +++ b/docs/build-and-packaging.md @@ -408,8 +408,8 @@ that brought it into the tree. It reads `bun.lock` and npm `package-lock.json`, and takes `:` to read a version from git: ```bash -node scripts/lockdiff.mjs origin/develop:bun.lock bun.lock -node scripts/lockdiff.mjs origin/develop:src/frontend/packages/devkit/package-lock.json \ +bun scripts/lockdiff.mjs origin/develop:bun.lock bun.lock +bun scripts/lockdiff.mjs origin/develop:src/frontend/packages/devkit/package-lock.json \ src/frontend/packages/devkit/package-lock.json --detail ``` diff --git a/docs/deploy/cloud-foundry/cloud-foundry.md b/docs/deploy/cloud-foundry/cloud-foundry.md index 0ae44bc6bc..e92ac2caf2 100644 --- a/docs/deploy/cloud-foundry/cloud-foundry.md +++ b/docs/deploy/cloud-foundry/cloud-foundry.md @@ -130,37 +130,21 @@ Each Stratos [GitHub release](https://github.com/cloudfoundry/stratos/releases) ### Deploy Stratos from source -To do so, `clone` the **stratos** repository, `cd` into the newly cloned repository and `push` to Cloud Foundry. This can be done with: +Build the same `cf push`-ready package a release contains, then push it. You need the tools in +[Required Runtimes](../../developer-environment.md#required-runtimes) installed locally. ``` git clone https://github.com/cloudfoundry/stratos cd stratos -git checkout tags/stable -b stable -./build/store-git-metadata.sh +git checkout # for example v5.5.5; omit to build the current develop branch +make install +make build release cf cf push ``` -If the cf push exceeds the time allowed see the instructions [here](#pre-building-the-ui) - -#### Pre-building the UI - -Due to the memory usage of the Angular compiler (see below), when deployed to Cloud Foundry via `cf push`, Stratos does not use AOT (Ahead-of-Time) compilation. - -If you wish to enable AOT or reduce the push time, you can pre-build the UI before pushing. - -This can be done with: - -``` -git clone https://github.com/cloudfoundry/stratos -cd stratos -npm install -npm run prebuild-ui -cf push -``` - -You will need a recent version of Node installed locally to do this. - -The `prebuild-ui` npm script performs a build of the front-end UI and then zips up the resulting folder into a package named `stratos-frontend-prebuild.zip`. The Stratos buildpack will unpack this zip file and use its contents instead of building the UI during staging, when this file is present. +`make build release cf` builds the UI, cross-compiles the backend for Linux/amd64 and stages both in `dist/cf-package`. The repository's +`manifest.yml` pushes that directory with the `binary_buildpack`, so nothing is built during staging. See +[CF Release Build Process](../../developer-environment.md#cf-release-build-process) for the individual steps. #### Memory Usage diff --git a/docs/developer/backend.md b/docs/developer/backend.md index ebc6c21df1..2c7f4763f1 100644 --- a/docs/developer/backend.md +++ b/docs/developer/backend.md @@ -11,7 +11,7 @@ We use Go Modules for dependency management. You will need the following installed/available: -* go 1.12 or later. +* Go at the version in [Required Runtimes](../developer-environment.md#required-runtimes). *For authentication, **either*** @@ -23,13 +23,13 @@ You will need the following installed/available: #### Build -From the `src/jetstream` folder, build the Stratos back-end with: +From the repository root, build the Stratos back-end for your machine with: ``` -npm run build-backend +make build backend PLATFORM=/ # for example darwin/arm64 or linux/amd64 ``` -The back-end executable is named `jetstream` and should be created within the `src/jetstream` folder. +The back-end executable is `dist/bin/jetstream`. `make dev backend` builds it for your machine automatically the first time, so the normal dev cycle needs no separate build. ### Configuration diff --git a/docs/developer/developers-guide-e2e-tests.md b/docs/developer/developers-guide-e2e-tests.md index a0c4414327..78a6439beb 100644 --- a/docs/developer/developers-guide-e2e-tests.md +++ b/docs/developer/developers-guide-e2e-tests.md @@ -110,60 +110,23 @@ Given the output of the script, the following template can be used to update the ``` ### Tidying up test generated CF entities -If tests are stopped before completing or fail to clean old test artifacts will exist in the CF. To clean some of these please see the script -at [deploy/ci/automation/e2e-clean-remnants.sh](https://github.com/cloudfoundry/stratos/blob/main/deploy/ci/automation/e2e-clean-remnants.sh) +If tests are stopped before completing or fail to clean old test artifacts will exist in the CF. Run `make e2e clean` to remove the +CF resources the tests label `stratos-e2e-test` (add `DRYRUN=yes` to see what it would delete). ## Running the tests -To run the tests against an instance of Stratos execute +To run the tests, starting a local Stratos for them on dedicated ports, execute ```bash -npm run e2e +make test e2e ``` -If running Stratos on `https://127.0.0.1:4200` then instead execute +To run them against a Stratos that is already running, set `E2E_BASE_URL`. For the dev frontend started with `make dev frontend`: ```bash -npm run e2e-dev +make test e2e E2E_BASE_URL=https://localhost:5440 ``` Additional test commands: -- `npm run e2e:ui` - Run tests with Playwright UI mode -- `npm run e2e:debug` - Run tests in debug mode -- `npm run e2e:headed` - Run tests in headed mode (see browser) -- `npm run e2e:report` - View test report - - -## Running tests on Browserstack - -You can run the E2E tests on Browserstack instead of with a local browser. - -To do so, configure the following environment variables: - -|Variable|Required|Description| -|---|---|---| -|BROWSERSTACK_USER|Yes|Your Browserstack user ID| -|BROWSERSTACK_KEY|Yes|Your Browserstack key| -|BROWSERSTACK_TARGET|Yes|The Browser (and OS) to use (see below)| -|BROWSERSTACK_PROJECT|No|Project name| -|BROWSERSTACK_BUILD|No|Build name| -|BROWSERSTACK_NAME|No|Name| -|BROWSERSTACK_RESOLUTION|No|Screen resolution to use| - -For more information on project, build and name, see: https://www.browserstack.com/automate/capabilities. - -The `BROWSERSTACK_TARGET` environment variable can be just a Browser name, e.g. `Chrome`, or a name and version (separated by a space), e.g. `Chrome 69`. - -You can also specify which OS to use by separating the OS and browser with a `/`, e.g. `Windows/Chrome`. You can also specify the OS version by separating with a space, e.g. `Windows 10/Chrome`. You can fully described the OS and Browser with `Windows 10/Chrome 69`. - -For more information on supported Operating Systems/devices and browsers, see https://www.browserstack.com/list-of-browsers-and-platforms?product=js_testing and https://playwright.dev/docs/test-runners. - -As an example, to run the E2E tests against a locally run Stratos dev system, use: - -``` -BROWSERSTACK_TARGET="Chrome" npm run e2e-dev -``` - -> Note: This assumes you have set the `BROWSERSTACK_USER` and `BROWSERSTACK_KEY` environment variables already. - -Running the tests in this manner uses the browserstack-local npm package to allow the tests to run against your local system. To ensure that `BrowserStackLocal` processes are not left running if a test run is aborted, all `BrowserStackLocal` processes are terminated when the E2E test process exits. - -> Note: When the E2E tests are run using BrowserStack, the test reporter is modified to include timing information to help correlate tests to the captured video of the test run. +- `bun run e2e:ui` - Run tests with Playwright UI mode +- `bun run e2e:debug` - Run tests in debug mode +- `bun run e2e:headed` - Run tests in headed mode (see browser) +- `bun run e2e:report` - View test report diff --git a/docs/developer/frontend-tests.md b/docs/developer/frontend-tests.md index 7e22e8a6f1..a911c51011 100644 --- a/docs/developer/frontend-tests.md +++ b/docs/developer/frontend-tests.md @@ -5,77 +5,72 @@ sidebar_label: Tests ## Test +Run every command from the repository root. Stratos tooling runs through +[Bun](https://bun.sh); the `make` targets are the supported entry points. +[TESTING.md](https://github.com/cloudfoundry/stratos/blob/develop/TESTING.md) +has the full testing guide. + ### Lint -Run `npm run lint` to execute tslint lint checking. +Run `make check lint` to run the frontend and backend linters: ESLint over the +frontend packages and `e2e/`, then `gofmt`, `go vet` and `golangci-lint` over +each Go module. ### Unit tests -Run `npm test` to execute the unit tests via [Vitest](https://vitest.dev). Coverage information can be found in `./coverage` - -To execute an individual package run `npm run test:`. For example: -- `npm run test:core` - Test core package -- `npm run test:store` - Test store package -- `npm run test:cloud-foundry` - Test Cloud Foundry package +Run `make test frontend` to execute the unit tests via [Vitest](https://vitest.dev). -To run tests in watch mode: `npm run test:watch` +To narrow a run, name the Vitest project and, optionally, a path: -### End-to-end tests +- `make test frontend PROJECT=core`: test the core package +- `make test frontend PROJECT="core git"`: test several packages +- `make test frontend PROJECT=core SCOPE=src/frontend/packages/core/src/shared/components/stepper`: test one directory -Run `npm run e2e` to execute the end-to-end tests via [Playwright](https://playwright.dev/). +The projects are `core`, `store`, `cloud-foundry`, `kubernetes`, +`cf-autoscaler`, `git`, `shared` and `extension`. -Additional E2E commands: -- `npm run e2e:dev` - Run tests against local instance on `https://127.0.0.1:4200` -- `npm run e2e:ui` - Run tests with Playwright UI mode -- `npm run e2e:debug` - Run tests in debug mode -- `npm run e2e:headed` - Run tests in headed mode (see browser) -- `npm run e2e:report` - View test report +Other unit-test commands: -More information on the E2E tests and pre-requisites for running them is available here - [E2E Tests](developers-guide-e2e-tests.md). +- `make check coverage`: run the unit tests with coverage; the report is written to `./coverage` +- `bun run test:watch`: run Vitest in watch mode +- `bun run test:ui`: run Vitest with its browser UI -### Code Climate +Before opening a pull request, run `make check gate` (lint plus unit tests). -We use [Code Climate](https://codeclimate.com/github/cloudfoundry-incubator/stratos) to check for general code quality issues. This executes against Pull -Requests on creation/push. +### End-to-end tests -#### Running Code Climate locally -> Generally we would not advise doing this and just rely on the code climate gate to run when pull requests are submitted +Run `make test e2e` to execute the end-to-end tests via +[Playwright](https://playwright.dev/). It runs Chromium by default and starts a +local backend unless `E2E_BASE_URL` points at a deployed Stratos. -To run locally see instructions [here](https://github.com/codeclimate/codeclimate) to install Code Climate CLI -and engine via docker. Once set ensure you're in the root of the project and execute the following (it may take a while) +Useful options: -``` -codeclimate analyze -``` +- `make test e2e DRYRUN=yes`: list the tests that would run, without running them +- `make test e2e E2E_BROWSERS=chromium,firefox`: choose browsers (`all` runs every configured browser) +- `make test e2e E2E_BASE_URL=https://`: run against a deployed Stratos +- `make check e2e`: run only the core suites +- `make e2e clean`: remove the CF resources that test runs left behind -> [!NOTE] -> Unfortunately this highlights all current issues and not those that are the diff between any master and feature branch. Analyze -> can be ran against a single/sub set of files, again with all current issues, but a little more digestible. +For interactive work, call Playwright through the package scripts: -``` -codeclimate analyze -``` +- `bun run e2e:ui`: run tests with Playwright UI mode +- `bun run e2e:debug`: run tests in debug mode +- `bun run e2e:headed`: run tests in headed mode (see the browser) +- `bun run e2e:report`: view the last test report -In a feature branch to compare files that have changed to master, for instance, use the following +More information on the E2E tests and the prerequisites for running them is +available here - [E2E Tests](developers-guide-e2e-tests.md). -``` -git checkout feature-branch-A -codeclimate analyze $(git diff --name-only master) -``` +### Continuous integration -You can also run the above command via npm +Each pull request, and each push to it, runs these GitHub Actions checks: -``` -npm run climate -``` +- Lint check (`make check lint`) +- Frontend unit tests, one job per Vitest project +- Backend unit tests (`make test backend`) +- Build check (`make build frontend`, `make build backend`) +- CodeQL analysis for Go and JavaScript/TypeScript +- Docs lint, website build and booklets build +- Advisory checks: E2E impact (which E2E specs cover the change) and the changelog fragment -### Stratos Continue Integration -For each new pull request and any subsequent pushes to it the following actions are executed -- Code quality analysis via Code Climate - https://codeclimate.com/ -- Jenkins CI run, covering.. - - Frontend lint check - - Backend lint check - - Frontend unit tests - - Backend unit tests - - End to end tests -- Security anaylsis via Snyk - https://snyk.io/ +End-to-end tests are not part of the pull request checks. diff --git a/docs/developer/frontend.md b/docs/developer/frontend.md index b81754c3f3..10072e6aa1 100644 --- a/docs/developer/frontend.md +++ b/docs/developer/frontend.md @@ -18,48 +18,46 @@ If you feel comfortable with these and are happy with your dev environment pleas ## Set up Dependencies * Set up a Stratos backend. Both backend and frontend exist in this same repo. Follow the [Backend Development](./introduction.md#build--run-locally) set up guide. -* Install [NodeJs](https://nodejs.org) (if not already install) (minimum node version 12.13.0) -* Install [Angular CLI](https://cli.angular.io/) (if not already install) - `npm install -g @angular/cli` +* Install Node.js and Bun at the versions in [Required Runtimes](../developer-environment.md#required-runtimes). The Angular CLI comes with the project's dependencies; run it as `bunx ng`. ## Run the frontend -1. Run `npm install` -1. Run `npm start` for a dev server. (the app will automatically reload if you change any of the source files) - * If this times out please use `npm run start-high-mem` instead - * To change the port from the default 4200, add `-- --port [new port number]` - * To stop the automatic reload every time a resource changes add `-- --live-reload false` - * To do both the above use `-- --live-reload false --port [new port number]` -1. Navigate to `https://localhost:4200/`. The credentials to log in will be dependent on the Jetstream the console points at. Please refer +1. Run `make install` +1. Run `make dev frontend` for a dev server. The app reloads automatically when you change a source file. + * To change the ports, set `FRONTEND_PORT`, and `BACKEND_PORT` if the backend is not on 5443, for example + `make dev frontend FRONTEND_PORT=5540 BACKEND_PORT=5543` +1. Navigate to `https://localhost:5440/`. The credentials to log in will be dependent on the Jetstream the console points at. Please refer to the guides used when setting up the backend for more information ## Build > The normal dev cycle does not require a direct build. -Run `npm run build` to build the project. +Run `make build frontend` to build the frontend. -The build artefacts will be stored in the `dist/` directory. This will output a production build of the application. +The build artefacts will be stored in `dist/frontend/browser/`. This is a production build of the application. ## Creating angular items via angular cli -To create a new angular component run `ng generate component component-name`. You can use a similar command to create other types of angular -items `ng generate `. +To create a new angular component run `bunx ng generate component component-name`. You can use a similar command to create other types of angular +items `bunx ng generate `. ## Theming -We use the angular material theming mechanism. See [here](https://material.angular.io/guide/theming-your-components) for more information about theming new components added to stratos. +Stratos does not use Angular Material. Colours and other design tokens are CSS custom properties exposed to templates as Tailwind v4 classes. See +[Theming Architecture](../theming-architecture.md) and [Tailwind CSS v4 Usage](../tailwind-usage.md) before styling new components. ## Additional Information ### Extensions -Documentation on extensions can be found [here](../extensions/introduction.md). From a developers perspective extensions are managed by npm packages. +Documentation on extensions can be found [here](../extensions/introduction.md). From a developer's perspective extensions are packages. The default set are in `./src/frontend/packages`, any package added directly here will be automatically included by the build. -At build time the Stratos Devkit (`./src/frontend/packages/devkit`) will ensure all packages are imported correctly and theming, both component and console level, are applied correctly. -The devkit is automatically built in `postinstall` after `npm install` is ran. To directly build it `npm run dev-setup` can be executed. +At build time the Stratos Devkit (`./src/frontend/packages/devkit`) ensures all packages are imported correctly. +The devkit is built automatically by the `postinstall` step of `bun install` (which `make install` runs). To build it directly, run `bun run dev-setup`. ### Configuration diff --git a/docs/developer/introduction.md b/docs/developer/introduction.md index b72ad9c1c9..9d5125c081 100644 --- a/docs/developer/introduction.md +++ b/docs/developer/introduction.md @@ -16,21 +16,19 @@ Depending on what you are contributing, you will need to develop with the front- For a quick-start to get Stratos front and back ends built and running locally on a development system, follow the steps below. -You will need to have `go` and `nodejs` installed in your development environment. +You will need Node.js, Bun, Go, Git and Make; the [Required Runtimes](../developer-environment.md#required-runtimes) table lists the versions. ``` git clone https://github.com/cloudfoundry/stratos.git cd stratos -npm install -npm run build -npm run build-backend -cd src/jetstream -./jetstream +make install +make dev backend # terminal 1: backend on https://localhost:5443 +make dev frontend # terminal 2: frontend on https://localhost:5440 ``` -This will build both the frontend and backend and run the backend in a mode where it will also serve the static resources for the frontend. +Before the first `make dev backend`, create `src/jetstream/config.properties` with an encryption key and a login method; the contributor guide's [First-Time Setup](../contributing_guide.md#first-time-setup) gives the exact lines, including a local `admin` user. -You can open a web browser and navigate to (https://127.0.0.1:5443) and login with username `admin` and password `admin`. +Then open https://localhost:5440 in a web browser. > To develop the frontend we recommend reading through the [frontend](./frontend.md) doc. This includes a faster way to run Stratos and see your changes. diff --git a/docs/extensions/disable-packages.md b/docs/extensions/disable-packages.md index 9d494eb524..7fe423e631 100644 --- a/docs/extensions/disable-packages.md +++ b/docs/extensions/disable-packages.md @@ -4,24 +4,18 @@ title: Remove Stratos Packages sidebar_label: Remove Packages --- -Frontend packages and their associated backend plugins can be removed at build time via configuration. +Frontend packages and backend plugins can be removed at build time. They are configured separately: removing a frontend package does +not remove the backend plugins it uses. -## Frontend Package to Backend Plugin Dependencies +All of the methods below act when Stratos is built. A Cloud Foundry push of a release package (`binary_buildpack`) builds nothing +during staging, so set them before running `make build release cf`, not in `manifest.yml`. -Stratos NPM packages define a list of backend plugins that they require in order to function. These are found in the package's `package.json` in -the `stratos` section `backend` property. For instance the [Stratos Cloud Foundry](https://github.com/cloudfoundry/stratos/blob/main/src/frontend/packages/cloud-foundry/package.json) - package depends on multiple backend plugins. +## Remove frontend packages -If a backend package is not referenced by a package that is built and is not in the 'default' plugins [list](https://github.com/cloudfoundry/stratos/blob/main/src/jetstream/default_plugins.go) - then it will not be included in the backend build. Therefore omitting a frontend package will also most likely remove it's dependent plugins. +### Via stratos.yaml -> [!IMPORTANT] -> To ensure backend plugins are excluded correctly the npm target `prepare-backend` should run before building the backend the usual way with -> `build-backend`. If pushing Stratos to Cloud Foundry this step will be completed automatically after `npm install` runs within the buildpack. - -## Remove via stratos.yaml -Frontend packages can be removed from the build by adding them to the `excludes` section of `./stratos.yaml`. For example, to exclude -kubernetes and associated features add the kubernetes package to the excludes section before Stratos builds. +Frontend packages can be removed from the build by listing them under `packages.exclude` in `./stratos.yaml` at the repository root. +For example, to exclude Kubernetes and its features: ``` packages: @@ -29,18 +23,24 @@ packages: - '@stratosui/kubernetes' ``` -## Remove via environment variable -Similarly to adding to the exclude section in stratos.yaml, added a frontend package to the `STRATOS_BUILD_REMOVE` environment variable will - achieve the same outcome but easier to use when pushing Stratos to Cloud Foundry. For instance updating the env section of your `manifest.yml` - file as follows will exclude kubernetes and associated features from the build. +To keep the file elsewhere, point `STRATOS_YAML` at it. + +### Via environment variable + +Listing a frontend package in the `STRATOS_BUILD_REMOVE` environment variable has the same effect. Separate several packages with +commas. For example: ``` -applications: - - name: console - - env: - STRATOS_BUILD_REMOVE: "@stratosui/kubernetes" +STRATOS_BUILD_REMOVE=@stratosui/kubernetes make build release cf ``` -## Remove by deletion -Functionality can be removed by simply deleting the package from the folder structure. This should have the same effect as both methods above, - including automatically excluding any unreferences backend plugins. + +### By deletion + +Deleting a package from `src/frontend/packages` also removes it from the build. + +## Remove backend plugins + +The backend plugins compiled into Jetstream are listed in [`src/jetstream/plugin-config.yaml`](https://github.com/cloudfoundry/stratos/blob/develop/src/jetstream/plugin-config.yaml). +The plugins in the default [list](https://github.com/cloudfoundry/stratos/blob/develop/src/jetstream/default_plugins.go) are always +included. To remove a plugin, delete its entry from `plugin-config.yaml` before building the backend; `make build backend` regenerates +`extra_plugins.go` from that file. See [Plugin Architecture](../plugin-architecture.md) for details. diff --git a/docs/extensions/frontend.md b/docs/extensions/frontend.md index 916cca2dba..c77a7e18a1 100644 --- a/docs/extensions/frontend.md +++ b/docs/extensions/frontend.md @@ -309,7 +309,7 @@ productVersion: 2.0.0 In this example, we will walk through extending the Stratos front-end. A new tab will be added to the Cloud Foundry Application page. -This walk-through assumes that you have installed the Angular CLI globally - this can be done with `npm install -g @angular/cli`. +This walk-through uses the Angular CLI that comes with the project's dependencies; run it as `bunx ng`. ### Create a new extensions package diff --git a/docs/extensions/introduction.md b/docs/extensions/introduction.md index f14d0513d6..5a7a09d1a8 100644 --- a/docs/extensions/introduction.md +++ b/docs/extensions/introduction.md @@ -13,7 +13,7 @@ In order to customize Stratos, you will need to fork the Stratos GitHub reposito ### Frontend -Frontend customizations are placed in angular packages in the folder named `src/frontend/packages`. In the future you will be able to host these packages in npm and bring them into Stratos in the usual npm dependency way. There are no additional processes or build steps required for Stratos to then integrate these packages. All steps will be automatically applied under the hood during `npm install` and when `ng build`/`ng serve` runs. +Frontend customizations are placed in angular packages in the folder named `src/frontend/packages`. In the future you will be able to host these packages in npm and bring them into Stratos in the usual npm dependency way. There are no additional processes or build steps required for Stratos to then integrate these packages. All steps are applied automatically during `bun install` (run by `make install`) and when `make build frontend` or `make dev frontend` runs. Information on custom theming can be found in the [theming page](../theming-architecture.md). diff --git a/docs/images/Browserstack-logo.svg b/docs/images/Browserstack-logo.svg deleted file mode 100644 index 195f64d2fe..0000000000 --- a/docs/images/Browserstack-logo.svg +++ /dev/null @@ -1,90 +0,0 @@ - - - - -Browserstack-logo-white - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/introduction.md b/docs/introduction.md index f855495bd9..1dc397bbc2 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -43,8 +43,6 @@ Get an [Overview](overview.md) of Stratos, its components and the different ways Browse through features and issues in the project's [issues](https://github.com/cloudfoundry/stratos/issues) page. -What kind of code is in Stratos? We've integrated [Code Climate](https://codeclimate.com) for some code quality and maintainability metrics. Take a stroll around the [project page](https://codeclimate.com/github/cloudfoundry/stratos) - ## Contributing We very much welcome developers who would like to get involved and contribute to the development of the Stratos project. Please refer to the [Contributing guide](contributing_guide.md) for more information. diff --git a/docs/issue_template.md b/docs/issue_template.md index c8b8913393..40e46ed4d8 100644 --- a/docs/issue_template.md +++ b/docs/issue_template.md @@ -11,7 +11,7 @@ * [ ] Cloud Foundry Application (cf push) * [ ] Kubernetes, using a helm chart * [ ] Docker, single container deploying all components -* [ ] npm run start +* [ ] Local dev server (make dev frontend) * [ ] Other (please specify below) ### Backend (Jet Stream) Deployment type diff --git a/docs/pagination-architecture.md b/docs/pagination-architecture.md index 5e282fdbd2..668b6d4c27 100644 --- a/docs/pagination-architecture.md +++ b/docs/pagination-architecture.md @@ -1,484 +1,379 @@ # Pagination Architecture -Developer guide to the Stratos list pagination system. This covers the data flow from store to UI, the view toggle mechanism, the "All" page size handling, and common pitfalls. - -## Component Overview - -``` -ListComponent (list.component.ts) - ├── view$ ─── controls card/table toggle - ├── paginatorSettings ─── plain object bridging store → paginator - ├── PageSizeSessionService ─── in-memory per-view page size memory - │ - ├── AppPaginatorComponent (app-paginator.component.ts) - │ ├── pageSize @Input ─── setter resolves PAGE_SIZE_ALL - │ ├── selectValue getter ─── drives ` uses `[selected]` per-option rather than `[value]` on the select element: - -```html -