-
Notifications
You must be signed in to change notification settings - Fork 18
feat: Added React Demo webApp and deployment workflow #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a86a545
c69f6ff
e41f690
125eae9
6872ffb
d7c15cb
cd99b03
dd5b89e
0022308
f62b9bc
684e857
91d5c64
0a24153
85d83b1
b1de94a
df1b8ce
71bb8d2
fa85069
51d0af9
5a10fcc
dff043c
9bc4478
6b4de7c
9626c3b
07aca10
3fc1884
acef4c6
3084d50
a2c4e9d
5026d57
a2b111f
805acec
d4c1875
e5da9fa
4edeaad
96316c1
0824d32
b01f438
00f5936
0e96f9b
ef0e56f
6027eee
4d0c12f
ed6f6f1
cd37f3d
614574b
29d2a33
7506bfa
c1bd8e7
ab058fc
3ecb790
fe125a0
1e2a81e
af1b8f5
b580e0c
73453e1
53eab0a
3da2929
db4488d
a0b2bb9
4b584d3
af084c0
610c690
417f71f
b0ba768
05adc20
36bebdd
9ab6fc5
681689e
80d3e06
82ee280
30e500f
eee214e
94c52c2
10964a7
fce4987
c6be905
cce3084
4a2a712
1280d33
d828e1a
436c0be
140d829
1dd7b16
0230da8
3334e6c
fce8ba1
df0d79d
2de2578
9f3ed3b
88fe2f5
089eb71
02e7519
b1201fd
adf8bc4
883e029
3a36716
892f6c8
858487d
e4d1eb6
0625fa0
2b6cead
c4ae11d
71b963b
da59ef1
f1c33a7
25eedc8
5d00908
386de8e
cb2fae3
5b1f6f0
3f41680
569b283
ea2bfcf
4471f7b
bccf25c
c72cdcd
0afb87a
6e5888b
8087555
3aa315b
195361b
9c9263e
c4389ee
bdc82b0
e203c5c
4e73c76
c46a04e
2b4e599
d65631e
694df61
1be8f3c
032ae88
8fb5d11
6006bac
f737b36
057cea9
f8a6374
8090b68
9dc7710
af2732f
c22cbb3
3611ec8
e6ca6f7
f62fceb
adc2147
bdfdfa2
44a7753
fd194aa
2550523
500e5d7
26ec764
7528064
d65a7dc
fedfca4
6295d5d
ee663e5
31cfc8d
60dd345
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| name: Deploy React WebApps | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should think through which steps of the pipeline should run on which branches. We can use the Nimble workflow for inspiration. The strategy there is:
Unless you have reasons not to, I'd vote for similar philosophy here, which would involve changing this to run on all branches and changing the SL Login and Deploy steps to run only in main. I think it's ok for the pack and GitHub artifact steps to run on all branches; that could enable a dev workflow where you push changes to github to get your app built and then manually download the nipkg artifact from the build result and manually upload it to your local SystemLink. |
||
| - main | ||
| - master | ||
| - devOps/CI_CD | ||
| paths: | ||
| - "examples/web_apps/Framework_Examples/**" | ||
| - ".github/workflows/webapp_deploy.yml" | ||
| pull_request: | ||
| branches: | ||
| - main | ||
| - master | ||
| paths: | ||
| - "examples/web_apps/Framework_Examples/**" | ||
| - ".github/workflows/deploy.yml" | ||
|
|
||
| jobs: | ||
| build-package-deploy: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: # Add frameworks and Folder names here | ||
| include: | ||
| - framework: React | ||
| app-folder: ApiKeyAuthApp | ||
|
|
||
| # - framework: Angular | ||
| # app-folder: my-angular-app-1 # example entry | ||
|
|
||
| env: | ||
| NODE_VERSION: "24.x.x" | ||
| REACT_APPS_DIR: "examples/Web Applications/Framework Examples/React" | ||
| ANGULAR_APPS_DIR: "examples/Web Applications/Framework Examples/Angular" | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: ${{ env.NODE_VERSION }} | ||
|
|
||
| - name: Set App Directory | ||
| run: | | ||
| if [ "${{ matrix.framework }}" == "React" ]; then | ||
| echo "APP_DIR=${{ env.REACT_APPS_DIR }}/${{ matrix.app-folder }}" >> $GITHUB_ENV | ||
| else | ||
| echo "APP_DIR=${{ env.ANGULAR_APPS_DIR }}/${{ matrix.app-folder }}" >> $GITHUB_ENV | ||
| fi | ||
|
|
||
| - name: Install dependencies | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: npm ci | ||
|
|
||
| - name: Lint | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: npm run lint | ||
|
|
||
| - name: Build | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: npm run build | ||
|
|
||
| - name: Setup Homebrew + Install slcli | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not super familiar with the Just a suggestion, if my understanding is incorrect and that doesn't work then feel free to reject. |
||
| run: | | ||
| eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" | ||
| brew tap ni-kismet/homebrew-ni | ||
| brew install slcli | ||
| echo "/home/linuxbrew/.linuxbrew/bin" >> $GITHUB_PATH | ||
|
|
||
| - name: Package into .nipkg | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| WEBAPP_NAME=$(basename "$PWD") | ||
| slcli webapp pack dist/ --output "${WEBAPP_NAME}.nipkg" | ||
| echo "WEBAPP_NAME=${WEBAPP_NAME}" >> $GITHUB_ENV | ||
|
|
||
| - name: Upload .nipkg artifact to gitHub | ||
| uses: actions/upload-artifact@v6 | ||
| with: | ||
| name: ${{ matrix.app-folder }}.nipkg | ||
| path: ${{env.REACT_APPS_DIR}}/${{matrix.app-folder}}/${{env.WEBAPP_NAME}}.nipkg | ||
|
|
||
| - name: Login to SystemLink | ||
| run: | | ||
| slcli login --profile ghActions --url "${{ secrets.SL_API_URL }}" --api-key "${{ secrets.SL_API_KEY }}" --web-url "${{ secrets.SL_WEBSITE_URL }}" --workspace "${{secrets.SL_WORKSPACE}}" | ||
|
|
||
| - name: Deploy (publish new/update) webapp (nipkg) to NI internal SystemLink test tier | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| pkg=${{env.WEBAPP_NAME}}.nipkg | ||
| WEBAPP_NAME="$(basename "$pkg" .nipkg)_PROD" | ||
| echo "**Deploying "$pkg" "$WEBAPP_NAME"**" | ||
| WEBAPP_ID=$(slcli webapp list --workspace "${{ secrets.SL_WORKSPACE }}" --filter "$WEBAPP_NAME" --format json | jq -r '.[0].id // empty') | ||
| if [[ -z "$WEBAPP_ID" ]]; then | ||
| echo " *Webapp does not exist -- publishing new" | ||
| slcli webapp publish "$pkg" --name "$WEBAPP_NAME" --workspace "${{ secrets.SL_WORKSPACE }}" | ||
| else | ||
| echo " *Webapp exists -- updating" | ||
| slcli webapp publish "$pkg" --id "$WEBAPP_ID" | ||
| fi | ||
| echo "**Deployed "$WEBAPP_NAME"**" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| proxyConfig.js | ||
| node_modules/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # API Service Proxy | ||
|
|
||
| The API Service Proxy is used to **locally** run web applications that call | ||
| SystemLink APIs. | ||
|
|
||
| ## Purpose -- Local development | ||
|
|
||
| The API Service Proxy is used to forward requests to a SystemLink API server | ||
| (e.g. https://demo-api.lifecyclesolutions.ni.com). The forward proxy is | ||
| necessary because the API server does not allow cross origin sharing (no CORS). | ||
|
|
||
| The service proxy should be used when testing a web application in a local | ||
| environment. An api key is required to authorize requests made to a SystemLink | ||
| API server. | ||
|
|
||
| ### Do not make calls through the proxy in production | ||
|
|
||
| Web applications that are hosted in a SystemLink environment should route | ||
| requests to the environment's domain (i.e. | ||
| https://demo.lifecyclesolutions.ni.com). | ||
|
|
||
| The endpoints in the SystemLink deployment environment are the same as the | ||
| SystemLink API endpoints, but authorization is done via a cookie which the | ||
| browser will automatically send with the request. | ||
|
|
||
| ## Setup | ||
|
|
||
| 1. Install dependencies: | ||
|
|
||
| ```bash | ||
| npm ci | ||
| ``` | ||
|
|
||
| 2. Create a `proxyConfig.js` from `proxyConfig.example.js` and add your | ||
| SystemLink API URL and API key | ||
|
|
||
| 3. Start the backend server: | ||
|
|
||
| ```bash | ||
| node index.js | ||
| ``` | ||
|
|
||
| 4. Server will be running on `localhost:4000` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import express from "express"; | ||
|
|
||
| import cors from "cors"; | ||
|
|
||
| import { apiKey, apiServerUrl } from "./proxyConfig.js"; | ||
| const app = express(); | ||
| const PORT = 4000; | ||
|
|
||
| // Middleware | ||
| app.use(cors()); | ||
| app.use(express.json()); | ||
|
|
||
| // Simple proxy endpoint | ||
|
|
||
| app.all("/apiProxy/*splat", async (req, res) => { | ||
| const forwardPath = req.originalUrl.replace(/^\/apiProxy/, ""); | ||
| const forwardFullUrl = `${apiServerUrl}${forwardPath}`; | ||
|
|
||
| const forwardReq = { | ||
| method: req.method, | ||
| headers: { | ||
| "x-ni-api-key": apiKey, | ||
| }, | ||
| body: req.body, | ||
| }; | ||
|
|
||
| try { | ||
| const upstreamResponse = await fetch(forwardFullUrl, forwardReq); | ||
|
|
||
| if (!upstreamResponse.ok) { | ||
| return res.status(response.status).send({}); | ||
| } | ||
|
|
||
| const data = await upstreamResponse.json(); | ||
| res.json(data); | ||
| } catch (err) { | ||
| console.error(err); | ||
| res.status(500).send({ error: "Proxy server error" }); | ||
| } | ||
| }); | ||
|
|
||
| app.listen(PORT, () => { | ||
| console.log(`Proxy server running on http://localhost:${PORT}`); | ||
| }); |
Uh oh!
There was an error while loading. Please reload this page.