Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "Angular SDK Components",
"image": "mcr.microsoft.com/devcontainers/typescript-node:24",
"postCreateCommand": "npm ci --ignore-scripts && npx playwright install --with-deps chromium",
"forwardPorts": [3500],
"portsAttributes": { "3500": { "label": "SDK dev server" } },
"customizations": {
"vscode": {
"extensions": ["angular.ng-template", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "ms-playwright.playwright"]
}
}
}
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
dist
.angular
.git
**/*.tgz
test-results
tests/playwright-report
packages/angular-sdk-overrides/lib
keys
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
19 changes: 19 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copy to .env (git-ignored) and `source` it, or set these in your CI system.
# `npm run configure` applies them to sdk-config.json. Empty values are ignored.
# Full reference: docs/configuration.md

SDK_INFINITY_REST_SERVER_URL=https://my-pega.example.com/prweb
SDK_APP_ALIAS=MediaCo
SDK_PORTAL_CLIENT_ID=
SDK_MASHUP_CLIENT_ID=
SDK_MASHUP_USER_IDENTIFIER=
# Plain text here; the script Base64-encodes it into sdk-config.json
SDK_MASHUP_PASSWORD=
SDK_CONTENT_SERVER_URL=
SDK_APP_PORTAL=
SDK_APP_MASHUP_CASE_TYPE=
SDK_SHOW_MODALS_IN_EMBEDDED_MODE=false
SDK_THEME=dark

# End-to-end tests
SDK_E2E_BASE_URL=http://localhost:3500
21 changes: 21 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
run: npm run build-angular-sdk-components
- name: Public API report is up to date
run: npm run api:check
- name: Tooling script tests
run: npm run test:scripts
- name: Component catalogue is up to date
run: npm run docs:components:check
- name: noImplicitAny ratchet
Expand All @@ -49,3 +51,22 @@ jobs:
cache: npm
- run: npm ci --ignore-scripts
- run: npm run test:unit

docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t sdk-ci .
- name: Smoke test (config is rendered from SDK_* variables at start)
run: |
docker run -d --name sdk -p 8080:8080 \
-e SDK_INFINITY_REST_SERVER_URL=https://pega.example.com/prweb \
-e SDK_APP_ALIAS=SmokeApp sdk-ci
for i in $(seq 1 30); do curl -fsS http://localhost:8080/healthz && break; sleep 1; done
curl -fsS http://localhost:8080/sdk-config.json | grep -q '"appAlias": "SmokeApp"'
curl -fsS -o /dev/null http://localhost:8080/portal
curl -fsS -o /dev/null http://localhost:8080/embedded
- name: Container logs
if: failure()
run: docker logs sdk
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ packages/angular-sdk-overrides/SECURITY.md

**/tsconfig.*.tsbuildinfo
temp/

# local environment files
.env
.env.local
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ angular-sdk-components/
| `npm run check:any` / `check:any:update` | `noImplicitAny` per-file ratchet (do not add new implicit-any errors) |
| `npm run api:check` / `api:update` | Public API report guard (`etc/angular-sdk-components.api.md`) |
| `npm run check:overrides` | Type-check the generated overrides package against the built library |
| `npm run doctor` / `npm run configure` | Pre-flight environment check / render `sdk-config.json` from `SDK_*` env vars (see docs/configuration.md) |
| `npm run test:scripts` | Unit tests for the tooling scripts (`scripts/__tests__`) |
| `npm run docs:components` | Regenerate `docs/components.md` from the component map |

### Prerequisites
Expand Down
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# syntax=docker/dockerfile:1

# ---- build: compile the Angular app with the production configuration ----
FROM node:24-alpine AS build
WORKDIR /app
COPY package.json package-lock.json .npmrc ./
RUN npm ci --ignore-scripts
COPY . .
# Optional build-time sdk-config values; prefer runtime SDK_* variables (see docs/configuration.md)
RUN npm run prod-build-angularsdk

# ---- runtime: static files behind nginx, sdk-config.json generated from SDK_* env vars at start ----
FROM nginxinc/nginx-unprivileged:alpine AS runtime
USER root
RUN apk add --no-cache nodejs
COPY --from=build --chown=101:101 /app/dist /usr/share/nginx/html
COPY --chown=101:101 scripts/configure-sdk.js /opt/sdk/scripts/configure-sdk.js
COPY --chown=101:101 scripts/lib /opt/sdk/scripts/lib
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY --chmod=755 docker/entrypoint.sh /docker-entrypoint.d/40-sdk-config.sh
USER 101
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD wget -qO- http://127.0.0.1:8080/healthz || exit 1
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ with the Angular SDK using the information (including pointers to online documen
[**Pega Community**](https://community.pega.com/marketplace/component/angular-sdk) and the Angular SDK code
on [**GitHub**](https://community.pega.com/marketplace/component/angular-sdk).

## Quick start for developers

Clone this repository to build and customize your own Constellation Angular app, then:

```bash
npm ci
cp .env.example .env && $EDITOR .env # Infinity URL, OAuth client ID, ...
set -a; source .env; set +a
npm run configure # writes sdk-config.json from the environment
npm run doctor # pre-flight check of your setup
npm run start-dev # http://localhost:3500
```

| | |
| --- | --- |
| Setup walkthrough | [docs/getting-started.md](docs/getting-started.md) |
| Configuration reference (`sdk-config.json`, environment variables) | [docs/configuration.md](docs/configuration.md) |
| CI/CD (GitHub Actions, Azure DevOps, GitLab, Jenkins), Docker, E2E | [docs/ci-cd.md](docs/ci-cd.md) |
| Customize, override or add components | [docs/customizing.md](docs/customizing.md) |
| Troubleshooting | [docs/troubleshooting.md](docs/troubleshooting.md) |

## Packages in this repo

* [**angular-sdk-components**](https://www.npmjs.com/package/@pega/angular-sdk-components) <br />
Expand Down
39 changes: 39 additions & 0 deletions ci-templates/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Required credentials/env: SDK_INFINITY_REST_SERVER_URL, SDK_APP_ALIAS, SDK_PORTAL_CLIENT_ID (job env or folder properties),
// 'sdk-mashup-password' (secret text) and optionally SDK_E2E_BASE_URL.
pipeline {
agent { docker { image 'node:24' } }
options { timestamps() }
stages {
stage('Install') { steps { sh 'npm ci --ignore-scripts' } }
stage('Pre-flight') { steps { sh 'npm run doctor -- --offline' } }
stage('Lint') { steps { sh 'npm run lint' } }
stage('Configure') {
steps {
withCredentials([string(credentialsId: 'sdk-mashup-password', variable: 'SDK_MASHUP_PASSWORD')]) {
sh 'npm run configure'
}
}
}
stage('Build') {
steps {
sh 'npm run prod-build-angularsdk'
archiveArtifacts artifacts: 'dist/**', fingerprint: true
}
}
stage('E2E') {
when { expression { return env.SDK_E2E_BASE_URL?.trim() } }
agent { docker { image 'mcr.microsoft.com/playwright:v1.63.0-jammy' } }
environment { CI = 'true'; PW_SLOW_MO = '0' }
steps {
sh 'npm ci --ignore-scripts'
sh 'npm test'
}
post {
always {
junit 'test-results/junit.xml'
archiveArtifacts artifacts: 'tests/playwright-report/**', allowEmptyArchive: true
}
}
}
}
}
66 changes: 66 additions & 0 deletions ci-templates/azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copy to azure-pipelines.yml
# Define these variables on the pipeline (mark SDK_MASHUP_PASSWORD as secret):
# SDK_INFINITY_REST_SERVER_URL, SDK_APP_ALIAS, SDK_PORTAL_CLIENT_ID, SDK_MASHUP_PASSWORD, SDK_E2E_BASE_URL (optional)
trigger:
branches:
include: [main, master]
pr:
branches:
include: ['*']

pool:
vmImage: ubuntu-latest

stages:
- stage: Build
jobs:
- job: build
steps:
- task: NodeTool@0
inputs:
versionSource: fromFile
versionFilePath: .nvmrc
- script: npm ci --ignore-scripts
displayName: Install
- script: npm run doctor -- --offline
displayName: Pre-flight
- script: npm run lint
displayName: Lint
- script: npm run configure
displayName: Render sdk-config.json
env:
SDK_INFINITY_REST_SERVER_URL: $(SDK_INFINITY_REST_SERVER_URL)
SDK_APP_ALIAS: $(SDK_APP_ALIAS)
SDK_PORTAL_CLIENT_ID: $(SDK_PORTAL_CLIENT_ID)
SDK_MASHUP_PASSWORD: $(SDK_MASHUP_PASSWORD)
- script: npm run prod-build-angularsdk
displayName: Production build
- publish: dist
artifact: sdk-dist

- stage: E2E
dependsOn: Build
condition: and(succeeded(), ne(variables['SDK_E2E_BASE_URL'], ''))
jobs:
- job: playwright
steps:
- task: NodeTool@0
inputs:
versionSource: fromFile
versionFilePath: .nvmrc
- script: npm ci --ignore-scripts && npx playwright install --with-deps chromium
displayName: Install
- script: npm test
displayName: Playwright
env:
CI: 'true'
PW_SLOW_MO: '0'
SDK_E2E_BASE_URL: $(SDK_E2E_BASE_URL)
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: JUnit
testResultsFiles: test-results/junit.xml
- publish: tests/playwright-report
artifact: playwright-report
condition: always()
76 changes: 76 additions & 0 deletions ci-templates/github-actions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copy to .github/workflows/sdk-ci.yml
#
# Required repository settings
# Variables (Settings > Secrets and variables > Actions > Variables):
# SDK_INFINITY_REST_SERVER_URL, SDK_APP_ALIAS, SDK_PORTAL_CLIENT_ID, SDK_E2E_BASE_URL (optional, deployed env for E2E)
# Secrets: SDK_MASHUP_PASSWORD (only if you use the embedded/mashup flow)
name: sdk-ci

on:
pull_request:
push:
branches: [main, master]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: sdk-ci-${{ github.ref }}
cancel-in-progress: true

env:
SDK_INFINITY_REST_SERVER_URL: ${{ vars.SDK_INFINITY_REST_SERVER_URL }}
SDK_APP_ALIAS: ${{ vars.SDK_APP_ALIAS }}
SDK_PORTAL_CLIENT_ID: ${{ vars.SDK_PORTAL_CLIENT_ID }}
SDK_MASHUP_PASSWORD: ${{ secrets.SDK_MASHUP_PASSWORD }}

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci --ignore-scripts
- name: Pre-flight (no network)
run: npm run doctor -- --offline
- name: Lint
run: npm run lint
- name: Render sdk-config.json from environment
run: npm run configure
- name: Production build
run: npm run prod-build-angularsdk
- uses: actions/upload-artifact@v4
with:
name: sdk-dist
path: dist
retention-days: 7

e2e:
# Runs against an already deployed environment; remove this job if you have no E2E environment.
if: ${{ vars.SDK_E2E_BASE_URL != '' }}
needs: build
runs-on: ubuntu-latest
env:
CI: 'true'
SDK_E2E_BASE_URL: ${{ vars.SDK_E2E_BASE_URL }}
PW_SLOW_MO: '0'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci --ignore-scripts
- run: npx playwright install --with-deps chromium
- run: npm test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: |
tests/playwright-report
test-results
39 changes: 39 additions & 0 deletions ci-templates/gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copy to .gitlab-ci.yml
# CI/CD variables: SDK_INFINITY_REST_SERVER_URL, SDK_APP_ALIAS, SDK_PORTAL_CLIENT_ID, SDK_MASHUP_PASSWORD (masked), SDK_E2E_BASE_URL (optional)
image: node:24

stages: [build, e2e]

cache:
key:
files: [package-lock.json]
paths: [.npm/]

build:
stage: build
script:
- npm ci --ignore-scripts --cache .npm --prefer-offline
- npm run doctor -- --offline
- npm run lint
- npm run configure
- npm run prod-build-angularsdk
artifacts:
paths: [dist]
expire_in: 1 week

e2e:
stage: e2e
image: mcr.microsoft.com/playwright:v1.63.0-jammy
rules:
- if: $SDK_E2E_BASE_URL
variables:
CI: 'true'
PW_SLOW_MO: '0'
script:
- npm ci --ignore-scripts --cache .npm --prefer-offline
- npm test
artifacts:
when: always
paths: [tests/playwright-report, test-results]
reports:
junit: test-results/junit.xml
8 changes: 8 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
# Runs before nginx starts (nginx image executes /docker-entrypoint.d/*.sh): renders sdk-config.json from SDK_* variables.
set -eu

WEB_ROOT="${SDK_WEB_ROOT:-/usr/share/nginx/html}"
SCRIPT_DIR="${SDK_SCRIPT_DIR:-/opt/sdk/scripts}"

node "$SCRIPT_DIR/configure-sdk.js" --file "$WEB_ROOT/sdk-config.json" --out "$WEB_ROOT/sdk-config.json"
Loading
Loading