diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index ea99f6f..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,40 +0,0 @@ -version: 2.1 - -workflows: - test: - jobs: - - build-run-linux: - context: hello-world-demos - - test-daily: - triggers: - - schedule: - cron: "0 6 * * *" - filters: - branches: - only: main - jobs: - - build-run-linux: - context: hello-world-demos - -# This CI build ensures that the demo both compiles and works correctly. For the runtime test, -# we use an SDK key and flag key that are passed in via the CircleCI project configuration; -# the flag is configured to return a true value. - -jobs: - build-run-linux: - docker: - - image: circleci/node:latest - steps: - - checkout - - run: - name: insert SDK key and flag key into demo code - command: | - sed -i.bak "s/sdkKey *= *\".*\"/sdkKey = \"${LD_HELLO_WORLD_SDK_KEY}\"/" index.ts - sed -i.bak "s/featureFlagKey *= *\".*\"/featureFlagKey = \"${LD_HELLO_WORLD_FLAG_KEY_WITH_TRUE_VALUE}\"/" index.ts - - run: npm install - - run: - name: run demo - command: | - npm start | tee output.txt - grep "is true for this context" output.txt || (echo "Flag did not evaluate to expected true value" && exit 1) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a515dc2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: Verify Hello App +on: + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '0 9 * * *' + push: + branches: [ main, 'feat/**' ] + paths-ignore: + - '**.md' # Do not need to run CI for markdown changes. + pull_request: + branches: [ main, 'feat/**' ] + paths-ignore: + - '**.md' + +jobs: + build-and-run: + runs-on: ubuntu-latest + + permissions: + id-token: write # Needed if using OIDC to get release secrets. + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + + - run: npm i + + - uses: launchdarkly/gh-actions/actions/verify-hello-app@verify-hello-app-v2.0.1 + with: + use_server_key: true + role_arn: ${{ vars.AWS_ROLE_ARN }} + command: npm start diff --git a/index.ts b/index.ts index ea6bdc7..e9291ae 100644 --- a/index.ts +++ b/index.ts @@ -1,45 +1,71 @@ import * as LaunchDarkly from '@launchdarkly/node-server-sdk'; // Set sdkKey to your LaunchDarkly SDK key. -const sdkKey = ""; +const sdkKey = process.env.LAUNCHDARKLY_SDK_KEY ?? 'your-sdk-key'; // Set featureFlagKey to the feature flag key you want to evaluate. -const featureFlagKey = "my-boolean-flag"; +const featureFlagKey = process.env.LAUNCHDARKLY_FLAG_KEY ?? 'sample-feature'; -// Set up the context properties. This use should appear on your LaunchDarkly -// contexts dashboard soon after you run the demo. +function showBanner() { + console.log( + ` ██ + ██ + ████████ + ███████ +██ LAUNCHDARKLY █ + ███████ + ████████ + ██ + ██ +`, + ); +} + +function printValueAndBanner(flagValue: boolean) { + console.log(`*** The '${featureFlagKey}' feature flag evaluates to ${flagValue}.`); + + if (flagValue) showBanner(); +} + +if (!sdkKey) { + console.log('*** Please edit index.js to set sdkKey to your LaunchDarkly SDK key first.'); + process.exit(1); +} + + +const ldClient = LaunchDarkly.init(sdkKey); + +// Set up the context properties. This context should appear on your LaunchDarkly contexts dashboard +// soon after you run the demo. const context = { - "kind": "user", - "name": "Sandy", - "key": "example-context-key" + kind: 'user', + key: 'example-user-key', + name: 'Sandy', }; -function showMessage(s: string) { - console.log("*** " + s); - console.log(""); -} +async function main() { + try { + await ldClient.waitForInitialization({timeout: 10}); -const client = LaunchDarkly.init(sdkKey); - -client.once('ready', function () { - showMessage("SDK successfully initialized!"); - client.variation(featureFlagKey, context, false, function (err, showFeature) { - client.track("event-called", context); - if (showFeature) { - // application code to show the feature - showMessage("Feature flag '" + featureFlagKey + "' is true for this context"); - } else { - // the code to run if the feature is off - showMessage("Feature flag '" + featureFlagKey + "' is false for this context"); - } + console.log('*** SDK successfully initialized!'); - // Here we ensure that the SDK shuts down cleanly and has a chance to deliver analytics - // events to LaunchDarkly before the program exits. If analytics events are not delivered, - // the context properties and flag usage statistics will not appear on your dashboard. In a - // normal long-running application, the SDK would continue running and events would be - // delivered automatically in the background. - client.flush(function () { - client.close(); + const eventKey = `update:${featureFlagKey}`; + ldClient.on(eventKey, async () => { + const flagValue = await ldClient.variation(featureFlagKey, context, false); + printValueAndBanner(flagValue); }); - }); -}); + + const flagValue = await ldClient.variation(featureFlagKey, context, false); + printValueAndBanner(flagValue); + + if (typeof process.env.CI !== "undefined") { + process.exit(0); + } + } catch (error) { + console.log(`*** SDK failed to initialize: ${error}`); + process.exit(1); + } + +} + +main(); diff --git a/package.json b/package.json index ceae127..1c8fdf3 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,11 @@ "author": "LaunchDarkly ", "license": "Apache-2.0", "devDependencies": { - "@types/node": "20.4.2", - "ts-node": "10.9.1", - "typescript": "5.1.6" + "@types/node": "22.10.1", + "ts-node": "10.9.2", + "typescript": "5.7.2" }, "dependencies": { - "@launchdarkly/node-server-sdk": ">= 8.0.0" + "@launchdarkly/node-server-sdk": ">= 9.0.0" } } diff --git a/tsconfig.json b/tsconfig.json index 10580fe..0cd2d98 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,8 @@ { "compilerOptions": { - "module": "commonjs", - "strict": true + "module": "NodeNext", + "strict": true, + "target": "ES2020", + "moduleResolution": "NodeNext", } -} \ No newline at end of file +}