@@ -33,7 +33,50 @@ USE_NODE = NVM_SH="$${NVM_DIR:-$$HOME/.nvm}/nvm.sh"; \
3333 [ -s "$$NVM_SH" ] || NVM_SH="$$(brew --prefix nvm 2>/dev/null ) /nvm.sh"; \
3434 if [ -s "$$NVM_SH" ]; then . "$$NVM_SH" >/dev/null && nvm install >/dev/null 2>&1 && nvm use >/dev/null 2>&1; fi
3535
36- .PHONY : all help dev dev-pulse build-ui build build-cli run run-cli install-air install-pulse clean test test-cli install-ui setup-workspace work-init work-clean docs docker-image docker-run cleanup-enterprise mod-tidy test-integrations-py test-integrations-ts install-playwright run-e2e run-e2e-ui run-e2e-headed format ui
36+ # Decides how to expose secrets to a recipe. Set via:
37+ # INFISICAL=1 -> always wrap commands with `infisical run --path <p> --` (non-interactive)
38+ # INFISICAL=0 -> always source ./.env (non-interactive)
39+ # INFISICAL_PATH=/x -> override the Infisical secret path (default /local)
40+ # unset + tty -> prompt the user
41+ # unset + CI -> default to dotenv silently
42+ # After invoking `$(EXPOSE_ENV);`, prefix each command with `$$CMD_PREFIX` so it inherits the chosen secrets.
43+ # Use as: `$(EXPOSE_ENV); $$CMD_PREFIX <your command>`
44+ define EXPOSE_ENV
45+ if [ -n "$$INFISICAL" ]; then \
46+ case "$$INFISICAL" in \
47+ 1|y|Y|yes|YES|true|TRUE) USE_INFISICAL=1 ;; \
48+ *) USE_INFISICAL=0 ;; \
49+ esac; \
50+ elif [ -t 0 ]; then \
51+ printf "$(CYAN ) Use Infisical to expose secrets to this run? [y/N] $(NC ) "; \
52+ read ENV_ANSWER; \
53+ case "$$ENV_ANSWER" in \
54+ y|Y|yes|YES) USE_INFISICAL=1 ;; \
55+ *) USE_INFISICAL=0 ;; \
56+ esac; \
57+ else \
58+ USE_INFISICAL=0; \
59+ fi; \
60+ if [ "$$USE_INFISICAL" = "1" ]; then \
61+ if ! which infisical > /dev/null 2>&1; then \
62+ $(ECHO ) "$(RED ) infisical CLI not found. Install: https://infisical.com/docs/cli/overview$(NC ) "; \
63+ exit 1; \
64+ fi; \
65+ INFISICAL_PATH_VAL="$${INFISICAL_PATH:-/local}"; \
66+ $(ECHO ) "$(GREEN ) Secrets via Infisical (path=$$INFISICAL_PATH_VAL)$(NC ) "; \
67+ CMD_PREFIX="infisical run --path $$INFISICAL_PATH_VAL --"; \
68+ else \
69+ if [ -f .env ]; then \
70+ $(ECHO ) "$(YELLOW ) Loading environment variables from .env...$(NC ) "; \
71+ set -a; . ./.env; set +a; \
72+ else \
73+ $(ECHO ) "$(YELLOW ) No .env found - using current shell environment$(NC ) "; \
74+ fi; \
75+ CMD_PREFIX=""; \
76+ fi
77+ endef
78+
79+ .PHONY : all help dev dev-pulse build-ui build build-cli run run-cli install-air install-pulse clean test test-cli install-ui setup-workspace work-init work-clean docs docker-image docker-run cleanup-enterprise mod-tidy test-integrations-py test-integrations-ts install-playwright run-e2e run-e2e-ui run-e2e-headed format ui install-newman run-provider-harness-test
3780
3881all : help
3982
@@ -1484,3 +1527,96 @@ test-cli: install-gotestsum ## Run CLI tests
14841527 --format=$(GOTESTSUM_FORMAT ) \
14851528 --junitfile=../$(TEST_REPORTS_DIR ) /cli.xml \
14861529 -- ./...
1530+
1531+ install-newman : # # Install newman + htmlextra reporter if not already installed
1532+ @$(USE_NODE ) ; which newman > /dev/null 2>&1 || ($( ECHO) " $( YELLOW) Installing newman...$( NC) " && npm install -g newman)
1533+ @$(USE_NODE ) ; npm list -g newman-reporter-htmlextra > /dev/null 2>&1 || ($( ECHO) " $( YELLOW) Installing newman-reporter-htmlextra...$( NC) " && npm install -g newman-reporter-htmlextra)
1534+ @$(ECHO ) " $( GREEN) Newman + htmlextra are ready$( NC) "
1535+
1536+ run-provider-harness-test : install-newman # # Run the Bifrost provider-harness Postman collection via newman, opens an interactive HTML viewer with resend support afterwards. Set CI=1 to skip the viewer and just emit tmp/newman-report.html as a CI artifact. Prompts for Infisical-vs-.env (Usage: make run-provider-harness-test [BASE_URL=...] [APP_DIR=...] [FOLDER="..."] [ENV_FILE=...] [INFISICAL=1|0] [INFISICAL_PATH=/local] [VIEWER_PORT=8090] [CI=1])
1537+ @mkdir -p tmp
1538+ @$(EXPOSE_ENV ) ; \
1539+ BASE_URL_VAL=" $( or $( BASE_URL) ,http://localhost:8080) " ; \
1540+ APP_DIR_VAL=" $( or $( APP_DIR) ,tests/integrations/python) " ; \
1541+ VIEWER_PORT_VAL=" $( or $( VIEWER_PORT) ,8090) " ; \
1542+ STARTED_BY_US=0; \
1543+ cleanup () { \
1544+ if [ -f tmp/harness-viewer.pid ]; then \
1545+ VPID=$$(cat tmp/harness-viewer.pid ) ; \
1546+ kill $$ VPID 2> /dev/null; \
1547+ rm -f tmp/harness-viewer.pid; \
1548+ fi ; \
1549+ if [ " $$ STARTED_BY_US" = " 1" ] && [ -f tmp/bifrost-dev.pid ]; then \
1550+ BPID=$$(cat tmp/bifrost-dev.pid ) ; \
1551+ $(ECHO ) " $( YELLOW) Stopping Bifrost (pid $$ BPID) - we started it...$( NC) " ; \
1552+ kill $$ BPID 2> /dev/null; \
1553+ pkill -P $$ BPID 2> /dev/null; \
1554+ rm -f tmp/bifrost-dev.pid; \
1555+ fi ; \
1556+ }; \
1557+ preempt_viewer_port () { \
1558+ if [ -f tmp/harness-viewer.pid ]; then \
1559+ OLD=$$(cat tmp/harness-viewer.pid ) ; \
1560+ if kill -0 $$ OLD 2> /dev/null; then \
1561+ $(ECHO ) " $( YELLOW) Killing orphaned viewer pid $$ OLD from a prior run...$( NC) " ; \
1562+ kill $$ OLD 2> /dev/null; sleep 1; \
1563+ fi ; \
1564+ rm -f tmp/harness-viewer.pid; \
1565+ fi ; \
1566+ pkill -f " tests/e2e/api/runners/harness-viewer.mjs" 2> /dev/null || true ; \
1567+ if command -v lsof > /dev/null 2>&1 && lsof -ti tcp:$$ VIEWER_PORT_VAL > /dev/null 2>&1 ; then \
1568+ $(ECHO ) " $( YELLOW) Port $$ VIEWER_PORT_VAL still in use - freeing it...$( NC) " ; \
1569+ lsof -ti tcp:$$ VIEWER_PORT_VAL | xargs kill 2> /dev/null || true ; \
1570+ sleep 1; \
1571+ fi ; \
1572+ }; \
1573+ trap cleanup EXIT INT TERM HUP; \
1574+ if curl -fsS --max-time 2 " $$ BASE_URL_VAL/health" > /dev/null 2>&1 ; then \
1575+ $(ECHO ) " $( GREEN) Bifrost already running at $$ BASE_URL_VAL$( NC) " ; \
1576+ else \
1577+ $(ECHO ) " $( YELLOW) Bifrost not running - launching 'make dev' (APP_DIR=$$ APP_DIR_VAL) in background...$( NC) " ; \
1578+ $$ CMD_PREFIX $(MAKE ) dev APP_DIR=" $$ APP_DIR_VAL" > tmp/bifrost-dev.log 2>&1 & \
1579+ echo $$ ! > tmp/bifrost-dev.pid; \
1580+ STARTED_BY_US=1; \
1581+ $(ECHO ) " $( CYAN) Waiting for Bifrost /health to respond (up to 60s)...$( NC) " ; \
1582+ for i in $$ (seq 1 30); do \
1583+ if curl -fsS --max-time 2 " $$ BASE_URL_VAL/health" > /dev/null 2>&1 ; then \
1584+ $(ECHO ) " $( GREEN) Bifrost is up$( NC) " ; break ; \
1585+ fi ; \
1586+ sleep 2; \
1587+ done ; \
1588+ if ! curl -fsS --max-time 2 " $$ BASE_URL_VAL/health" > /dev/null 2>&1 ; then \
1589+ $(ECHO ) " $( RED) Bifrost did not become healthy. See tmp/bifrost-dev.log$( NC) " ; \
1590+ exit 1; \
1591+ fi ; \
1592+ fi ; \
1593+ $(ECHO ) " $( YELLOW) Running Postman collection via newman against $$ BASE_URL_VAL...$( NC) " ; \
1594+ $(USE_NODE ) ; $$ CMD_PREFIX newman run tests/e2e/api/collections/provider-harness.json \
1595+ --env-var " baseUrl=$$ BASE_URL_VAL" \
1596+ $(if $(ENV_FILE ) ,--environment $(ENV_FILE ) ,) \
1597+ $(if $(FOLDER ) ,--folder "$(FOLDER ) ",) \
1598+ --reporters cli,json,htmlextra \
1599+ --reporter-json-export tmp/newman-report.json \
1600+ --reporter-htmlextra-export tmp/newman-report.html \
1601+ --reporter-htmlextra-title " Bifrost Provider Harness" \
1602+ --reporter-htmlextra-darkTheme; \
1603+ NEWMAN_EXIT=$$? ; \
1604+ $(ECHO ) " $( GREEN) Newman finished. Reports: tmp/newman-report.json + tmp/newman-report.html$( NC) " ; \
1605+ if [ -n " $( CI) " ] || [ -n " $$ CI" ]; then \
1606+ $(ECHO ) " $( CYAN) CI mode - skipping interactive viewer. Upload tmp/newman-report.html as a workflow artifact.$( NC) " ; \
1607+ else \
1608+ preempt_viewer_port; \
1609+ $(ECHO ) " $( CYAN) Launching interactive viewer on http://localhost:$$ VIEWER_PORT_VAL (Bifrost stays up for resend)...$( NC) " ; \
1610+ $(USE_NODE ) ; node tests/e2e/api/runners/harness-viewer.mjs --report tmp/newman-report.json --port $$ VIEWER_PORT_VAL & \
1611+ VIEWER_PID=$$ ! ; \
1612+ echo $$ VIEWER_PID > tmp/harness-viewer.pid; \
1613+ wait $$ VIEWER_PID; \
1614+ VIEWER_EXIT=$$? ; \
1615+ rm -f tmp/harness-viewer.pid; \
1616+ if [ $$ VIEWER_EXIT -ne 0 ]; then \
1617+ $(ECHO ) " $( RED) Viewer exited with code $$ VIEWER_EXIT (see message above).$( NC) " ; \
1618+ else \
1619+ $(ECHO ) " $( GREEN) Viewer closed.$( NC) " ; \
1620+ fi ; \
1621+ fi ; \
1622+ exit $$ NEWMAN_EXIT
0 commit comments