Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
61ea9b3
Remove old nginx conf
benc-uk May 14, 2025
bd8f3eb
Refreshed for eslint and all packages to latest
benc-uk May 14, 2025
93d2ecb
Fix run target dependency to ensure frontend modules are available be…
benc-uk May 14, 2025
a5fd42e
Refactor golangci-lint configuration for improved clarity and organiz…
benc-uk May 14, 2025
b89d948
golangci-lint fixes
benc-uk May 14, 2025
d04eb45
Update base images in Dockerfiles to latest stable versions
benc-uk May 14, 2025
922df08
Update Dapr sidecar images to latest version and clean up Dockerfile
benc-uk May 14, 2025
15b9ecc
Bump version to 0.8.6 in Makefile
benc-uk May 14, 2025
e309a16
Version bumps
benc-uk May 14, 2025
56dec7e
Major refactor of testing
benc-uk May 15, 2025
d2f54a8
Add Bruno collection
benc-uk May 15, 2025
602c47f
Add TypeSpec for API
benc-uk May 17, 2025
9607cf3
Update README.md to enhance Docker instructions and clarify identity …
benc-uk May 17, 2025
8f54633
Update CI workflow to use latest actions and Go version
benc-uk May 17, 2025
9386a54
Update CI workflows: add golangci-lint installation and upgrade check…
benc-uk May 17, 2025
e064a93
Refactor CI workflow: update integration test steps and remove unused…
benc-uk May 17, 2025
e994635
Update CI workflow and Makefile: add integration test reporting and i…
benc-uk May 17, 2025
0e43a0c
Update CI workflow: initialize Dapr and upgrade test reporting action…
benc-uk May 17, 2025
4e56730
Update CI workflow and Makefile: add golangci-lint installation, impr…
benc-uk May 17, 2025
9512601
Update CI workflow and Makefile: install go-junit-report, enhance tes…
benc-uk May 17, 2025
eb3f79d
Update CI workflow and Makefile: rename test report output files for …
benc-uk May 17, 2025
1e3506f
Update CI workflow: re-enable build and push Docker images job with p…
benc-uk May 17, 2025
36ea848
Update CI workflow and Makefile: standardize test report paths and im…
benc-uk May 17, 2025
a6aa799
Names for tests
benc-uk May 17, 2025
ab77335
Update README.md: add GitHub Actions workflow status badge
benc-uk May 17, 2025
5f1f6cf
Update CI workflow: replace sleep with inotifywait for API integratio…
benc-uk May 17, 2025
ef78a35
Update CI workflow: modify inotifywait to monitor specific file for A…
benc-uk May 17, 2025
15d2247
Update CI workflow: replace inotifywait with sleep for API integratio…
benc-uk May 17, 2025
b719028
Update .github/workflows/ci-build.yml
benc-uk May 17, 2025
e7db083
Update CI workflow to run API integration tests with a new URL check …
benc-uk May 17, 2025
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
64 changes: 56 additions & 8 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,92 @@ on:
permissions:
contents: read
packages: write
checks: write

env:
VERSION: 0.8.5
VERSION: 0.8.6
BUILD_INFO: "Build:development / Workflow:${{ github.workflow }} / RunId:${{ github.run_id }} / Ref:${{ github.ref }} / SHA:${{ github.sha }} / ImageTag:${{ github.run_id }}"
IMAGE_REG: ghcr.io
IMAGE_TAG: ${{ github.run_id }}

jobs:
# ===== Testing & code checking ======
tests-linting:
name: "Run Lint & All Tests"
runs-on: ubuntu-latest
outputs:
imageTag: ${{ steps.createTag.outputs.IMAGE_TAG }}

steps:
- name: "Checkout source"
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: "Set Go version and paths"
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: "^1.21.0"
go-version: "^1.24.0"

- name: "Install extra tools"
- name: "Install extra Go tools"
run: |
go install gotest.tools/gotestsum@latest
go install github.com/jstemmer/go-junit-report@latest
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

- name: "Check code & lint"
run: |
go get ./...
make lint

- name: "Run all unit tests"
run: make test
- name: "Run all unit tests and generate reports"
run: |
make test-report

- name: "Test Report (Frontend)"
uses: phoenix-actions/test-reporting@v15
if: success() || failure()
with:
name: Frontend Tests
path: test-reports/frontend.xml
reporter: java-junit

- name: "Test Report (Unit Tests)"
uses: phoenix-actions/test-reporting@v15
if: success() || failure()
with:
name: Unit Tests
path: test-reports/unit.xml
reporter: java-junit

- name: "Dapr tool installer"
uses: dapr/setup-dapr@v1
with:
version: "1.15.1"

- name: "Initialize Dapr"
run: |
dapr init

- name: "Run API integration tests, with report"
run: |
echo "Starting Dapr Store all components..."
make run &

echo "Waiting for API to start..."
./scripts/url-check.sh http://localhost:9000/v1.0/invoke/products/method/catalog prd001

echo "Running API tests..."
make test-api-report

- name: "Test Report (API)"
uses: phoenix-actions/test-reporting@v15
if: success() || failure()
with:
name: API Integration Tests
path: test-reports/api.xml
reporter: java-junit

# ===== Build container images ======
build-images:
name: "Build & Push Images"
runs-on: ubuntu-latest
needs: tests-linting
strategy:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: "Run all image builds"
run: |
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ components/*.yaml
web/frontend/coverage
**/node_modules/**
output/**
test-reports/
bin/**
.secrets
.secrets
*.xml
running
85 changes: 47 additions & 38 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -1,41 +1,50 @@
# =================================================================
# An opinionated config for linting Go code with golangci-lint
# See https://golangci-lint.run/usage/linters
# =================================================================

version: "2"
linters:
enable:
- revive # Replacement for golint
- gofmt # Runs gofmt as part of the linter
- wsl # Whitespace style enforcer, a matter of taste
- stylecheck # A few Go style rules
- misspell # Find misspelled words
- cyclop # Find cyclomatic complexity
- gocyclo # Also find cyclomatic complexity
- bodyclose # Check for HTTP body close errors
- nilerr # Find bad nil/err handling
- nilnil # Also find bad nil/err handling

linters-settings:
misspell:
locale: UK # Enable UK spelling

# Check struck tag naming
tagliatelle:
case:
use-field-name: true
- bodyclose
- cyclop
- gocyclo
- misspell
- nilerr
- nilnil
- revive
- staticcheck
- wsl
settings:
misspell:
locale: UK
revive:
confidence: 0.5
severity: error
enable-all-rules: false
rules:
json: goCamel
yaml: goCamel

revive:
severity: error
enable-all-rules: false
confidence: 0.5
rules:
# There are MANY rules you could enable...
# See https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md
# And https://golangci-lint.run/usage/linters/#revive
- name: line-length-limit
severity: error
arguments: [160]
- name: line-length-limit
arguments:
- 160
severity: error
tagliatelle:
case:
rules:
json: goCamel
yaml: goCamel
use-field-name: true
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gofmt
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
34 changes: 29 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
SERVICE_DIR := cmd
FRONTEND_DIR := web/frontend
OUTPUT_DIR := ./output
VERSION ?= 0.8.5
TEST_OUT_DIR := ./test-reports
VERSION ?= 0.8.6
BUILD_INFO ?= "Local makefile build"
DAPR_RUN_LOGLEVEL := warn

Expand All @@ -14,6 +14,7 @@ IMAGE_REG ?= ghcr.io
IMAGE_REPO ?= azure-samples/dapr-store
IMAGE_TAG ?= latest
IMAGE_PREFIX := $(IMAGE_REG)/$(IMAGE_REPO)
API_ENDPOINT := http://localhost:9000/v1.0/invoke

.EXPORT_ALL_VARIABLES:
.PHONY: help lint lint-fix test test-reports docker-build docker-run docker-stop docker-push bundle clean run stop
Expand All @@ -30,16 +31,28 @@ lint-fix: $(FRONTEND_DIR)/node_modules ## 📝 Lint & format, fixes errors and
golangci-lint run --modules-download-mode=mod --timeout=4m --fix ./...
cd $(FRONTEND_DIR); npm run lint-fix

test: ## 🎯 Unit tests for services and snapshot tests for SPA frontend
test: $(FRONTEND_DIR)/node_modules ## 🎯 Run unit tests for services and snapshot tests for SPA frontend
go test -v -count=1 ./$(SERVICE_DIR)/...
@cd $(FRONTEND_DIR); npm run test:unit

test-report: $(FRONTEND_DIR)/node_modules ## 🎯 Run unit tests and generate report
mkdir -p $(TEST_OUT_DIR)
go test -v -count=1 ./$(SERVICE_DIR)/... | go-junit-report -set-exit-code > $(TEST_OUT_DIR)/unit.xml
@cd $(FRONTEND_DIR); npm run test:unit:report

test-api: ## 🧪 Run API integration tests with httpYac
npx httpyac send api/api-tests.http --all --output short --var endpoint=$(API_ENDPOINT)

test-api-report: ## 🧪 Run API integration tests with httpYac & generate report
mkdir -p $(TEST_OUT_DIR)
npx httpyac send api/api-tests.http --all --output short --var endpoint=$(API_ENDPOINT) --junit > $(TEST_OUT_DIR)/api.xml

frontend: $(FRONTEND_DIR)/node_modules ## 💻 Build and bundle the frontend Vue SPA
cd $(FRONTEND_DIR); npm run build
cd $(SERVICE_DIR)/frontend-host; go build

clean: ## 🧹 Clean the project, remove modules, binaries and outputs
rm -rf output
rm -rf $(TEST_OUT_DIR)
Comment thread
benc-uk marked this conversation as resolved.
rm -rf $(FRONTEND_DIR)/node_modules
rm -rf $(FRONTEND_DIR)/dist
rm -rf $(FRONTEND_DIR)/coverage
Expand All @@ -49,14 +62,18 @@ clean: ## 🧹 Clean the project, remove modules, binaries and outputs
rm -rf $(SERVICE_DIR)/products/products
rm -rf $(SERVICE_DIR)/frontend-host/frontend-host

run: ## 🚀 Start & run everything locally as processes
clear-state: ## 💥 Clear all state from Redis (wipe the database)
docker run --rm --network host redis redis-cli flushall

run: $(FRONTEND_DIR)/node_modules ## 🚀 Start & run everything locally as processes
cd $(FRONTEND_DIR); npm run dev &
dapr run --app-id cart --app-port 9001 --log-level $(DAPR_RUN_LOGLEVEL) go run github.com/azure-samples/dapr-store/cmd/cart &
dapr run --app-id products --app-port 9002 --log-level $(DAPR_RUN_LOGLEVEL) go run github.com/azure-samples/dapr-store/cmd/products ./cmd/products/sqlite.db &
dapr run --app-id users --app-port 9003 --log-level $(DAPR_RUN_LOGLEVEL) go run github.com/azure-samples/dapr-store/cmd/users &
dapr run --app-id orders --app-port 9004 --log-level $(DAPR_RUN_LOGLEVEL) go run github.com/azure-samples/dapr-store/cmd/orders &
@sleep 6
@./scripts/local-gateway/run.sh &
@touch -m /tmp/dapr-store-running
@sleep infinity
@echo "!!! Processes may still be running, please run `make stop` in order to shutdown everything"

Expand All @@ -76,13 +93,20 @@ docker-stop: ## 🚫 Stop and remove local containers

stop: ## ⛔ Stop & kill everything started locally from `make run`
docker rm -f api-gateway || true
rm -f /tmp/dapr-store-running
dapr stop --app-id api-gateway
dapr stop --app-id cart
dapr stop --app-id products
dapr stop --app-id users
dapr stop --app-id orders
pkill cart; pkill users; pkill orders; pkill products; pkill main

api-spec: ## 📜 Generate OpenAPI spec & JSON schemas from TypeSpec
cd api/typespec; npm install --silent
rm -rf ./api/typespec/out
npx --package=@typespec/compiler tsp compile ./api/typespec/ --output-dir ./api/typespec/
mv ./api/typespec/out/* ./api/

# ===============================================================================

$(FRONTEND_DIR)/node_modules: $(FRONTEND_DIR)/package.json
Expand Down
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,20 @@ The following diagram shows all the components of the application and main inter
The application uses the following [Dapr Building Blocks](https://docs.dapr.io/developing-applications/building-blocks/) and APIs

- **Service Invocation** — The API gateway calls the four main microservices using HTTP calls to [Dapr service invocation](https://docs.dapr.io/developing-applications/building-blocks/service-invocation/service-invocation-overview/). This provides retries, mTLS and service discovery.
- **State** — State is held for *users* and *orders* using the [Dapr state management API](https://docs.dapr.io/developing-applications/building-blocks/state-management/state-management-overview/). The state provider used is Redis, however any other provider could be plugged in without any application code changes.
- **State** — State is held for _users_ and _orders_ using the [Dapr state management API](https://docs.dapr.io/developing-applications/building-blocks/state-management/state-management-overview/). The state provider used is Redis, however any other provider could be plugged in without any application code changes.
- **Pub/Sub** — The submission of new orders through the cart service, is decoupled from the order processing via pub/sub messaging and the [Dapr pub/sub messaging API](https://docs.dapr.io/developing-applications/building-blocks/pubsub/pubsub-overview/). New orders are placed on a topic as messages, to be collected by the orders service. This allows the orders service to independently scale and separates our reads & writes
- **Output Bindings** — To communicate with downstream & 3rd party systems, the [Dapr Bindings API](https://docs.dapr.io/developing-applications/building-blocks/bindings/bindings-overview/) is used. This allows the system to carry out tasks such as saving order details into external storage (e.g. Azure Blob) and notify uses with emails via SendGrid
- **Middleware** — Dapr supports a range of HTTP middleware, for this project traffic rate limiting can enabled on any of the APIs with a single Kubernetes annotation

# Project Status

![](https://img.shields.io/github/last-commit/azure-samples/dapr-store) ![](https://img.shields.io/github/release-date/azure-samples/dapr-store) ![](https://img.shields.io/github/v/release/azure-samples/dapr-store) ![](https://img.shields.io/github/commit-activity/m/azure-samples/dapr-store)

![](https://img.shields.io/github/last-commit/azure-samples/dapr-store) ![](https://img.shields.io/github/release-date/azure-samples/dapr-store) ![](https://img.shields.io/github/v/release/azure-samples/dapr-store) ![](https://img.shields.io/github/commit-activity/m/azure-samples/dapr-store) ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/Azure-Samples/dapr-store/ci-build.yml?branch=main)

# Application Elements & Services

The main elements and microservices that make up the Dapr Store system are described here

Each service uses the [Go REST API Starter Kit & Library](https://github.com/benc-uk/go-rest-api) as a starting basis. Most of the boilerplate and
Each service uses the [Go REST API Starter Kit & Library](https://github.com/benc-uk/go-rest-api) as a starting basis. Most of the boilerplate and
base code for handling requests and generally acting as a RESTful HTTP endpoint is handled by this package.

## Service Code
Expand Down Expand Up @@ -193,10 +192,10 @@ This is a (very) basic guide to running Dapr Store locally. Only instructions fo

### Prereqs

- Docker
- Docker (Podman _might_ work, but I've never tried it)
- GCC for CGO & go-sqlite3 (apt-get install build-essential)
- Go v1.20+
- Node.js v18+
- Go v1.23+
- Node.js v20+

### Setup

Expand All @@ -207,7 +206,7 @@ wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O
dapr init
```

First time only, you will need to setup *go-sqlite3* library
First time only, you will need to setup _go-sqlite3_ library

```bash
CGO_ENABLED=1 go install github.com/mattn/go-sqlite3
Expand Down Expand Up @@ -239,16 +238,20 @@ A makefile is provided to assist working with the project and building/running i
help 💬 This help message :)
lint 🔎 Lint & format, check to be run in CI, sets exit code on error
lint-fix 📝 Lint & format, fixes errors and modifies code
test 🎯 Unit tests for services and snapshot tests for SPA frontend
test-reports 📜 Unit tests with coverage and test reports (deprecated)
bundle 💻 Build and bundle the frontend Vue SPA
test 🎯 Unit tests for services and snapshot tests for SPA frontend
test-report 🎯 Unit tests and generate report
test-api 🧪 Run API integration tests with httpYac
test-api-report 🧪 Run API integration tests with httpYac & generate report
frontend 💻 Build and bundle the frontend Vue SPA
clean 🧹 Clean the project, remove modules, binaries and outputs
clear-state 💥 Clear all state from Redis (wipe the database)
run 🚀 Start & run everything locally as processes
docker-run 🐋 Run locally using containers and Docker compose
docker-build 🔨 Build all containers using Docker compose
docker-push 📤 Push all containers using Docker compose
docker-stop 🚫 Stop and remove local containers
stop ⛔ Stop & kill everything started locally from `make run`
api-spec 📜 Generate OpenAPI spec & JSON schemas from TypeSpec
```

# CI / CD
Expand All @@ -263,7 +266,7 @@ A set of CI and CD release GitHub actions workflows are included in `.github/wor

The default mode of operation for the Dapr Store is in "demo mode" where there is no identity provider configured, and no security enforcement on the APIs. This makes it simple to run and allows us to focus on the Dapr aspects of the project. In this mode a demo/dummy user account is used to sign-in and place orders in the store.

Optionally Dapr store can be configured utilise the [Microsoft identity platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/) (aka Microsoft Entra ID) as an identity provider. This then supports real user sign-in, and securing of the APIs.
Optionally Dapr store can be configured utilise the [Microsoft identity platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/) (aka Microsoft Entra ID) as an identity provider. When this is configured, the app supports real user sign-in, and the APIs are secured.

#### [📃 Extra Doc: Security, identity & authentication](./docs/auth-identity/)

Expand All @@ -277,12 +280,12 @@ All services support the following environmental variables. All settings are opt
- `AUTH_CLIENT_ID` - Used to enable integration with Azure AD for identity and authentication. Default is _blank_, which runs the service with no identity backend. See the [security, identity & authentication docs](#security-identity--authentication) for more details.
- `DAPR_STORE_NAME` - Name of the Dapr state component to use. Default is `statestore`

The following vars are used only by the *Cart* and *Orders* services:
The following vars are used only by the _Cart_ and _Orders_ services:

- `DAPR_ORDERS_TOPIC` - Name of the Dapr pub/sub topic to use for orders. Default is `orders-queue`
- `DAPR_PUBSUB_NAME` - Name of the Dapr pub/sub component to use for orders. Default is `pubsub`

The following vars are only used by the *Orders* service:
The following optional vars are only used by the _Orders_ service:

- `DAPR_EMAIL_NAME` - Name of the Dapr SendGrid component to use for sending order emails. Default is `orders-email`
- `DAPR_REPORT_NAME` - Name of the Dapr Azure Blob component to use for saving order reports. Default is `orders-report`
Expand Down
Loading
Loading