soajs.controller 4.2.42 → 4.2.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +43 -0
- package/.github/workflows/release.yml +92 -0
- package/ARCHITECTURE.md +193 -0
- package/Gruntfile.js +1 -1
- package/docs/configuration-custom-registry.md +421 -0
- package/docs/configuration-services-config.md +275 -0
- package/docs/data-flow.md +138 -0
- package/docs/deployment.md +205 -0
- package/docs/external-integrations.md +159 -0
- package/docs/gateway-routes.md +259 -0
- package/docs/maintenance-routes.md +308 -0
- package/docs/middleware/awareness.md +120 -0
- package/docs/middleware/cors.md +88 -0
- package/docs/middleware/enhancer.md +75 -0
- package/docs/middleware/favicon.md +36 -0
- package/docs/middleware/gotoService.md +146 -0
- package/docs/middleware/ip2ban.md +70 -0
- package/docs/middleware/key.md +196 -0
- package/docs/middleware/keyACL.md +139 -0
- package/docs/middleware/lastSeen.md +111 -0
- package/docs/middleware/maintenanceMode.md +81 -0
- package/docs/middleware/mt.md +188 -0
- package/docs/middleware/oauth.md +173 -0
- package/docs/middleware/response.md +106 -0
- package/docs/middleware/soajs.md +71 -0
- package/docs/middleware/traffic.md +190 -0
- package/docs/middleware/url.md +102 -0
- package/docs/multi-tenant-security.md +183 -0
- package/docs/request-flow.md +230 -0
- package/docs/service-discovery.md +167 -0
- package/mw/key/index.js +16 -1
- package/mw/mt/urac.js +21 -1
- package/mw/mt/utils.js +2 -0
- package/package.json +7 -7
- package/test/unit/mw/key/index.js +150 -0
- package/test/unit/mw/mt/urac.js +157 -4
- package/.travis.yml +0 -72
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master, develop, feature/*, features/* ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master, develop ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
services:
|
|
14
|
+
mongodb:
|
|
15
|
+
image: mongo:6
|
|
16
|
+
ports:
|
|
17
|
+
- 27017:27017
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout code
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Setup Node.js
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: '20'
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm install
|
|
30
|
+
|
|
31
|
+
- name: Install grunt-cli
|
|
32
|
+
run: npm install -g grunt-cli
|
|
33
|
+
|
|
34
|
+
- name: Run linting
|
|
35
|
+
run: grunt
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
if: github.ref != 'refs/heads/master'
|
|
39
|
+
run: grunt test
|
|
40
|
+
|
|
41
|
+
- name: Run coverage
|
|
42
|
+
if: github.ref == 'refs/heads/master'
|
|
43
|
+
run: grunt coverage
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ release, release/* ]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
services:
|
|
12
|
+
mongodb:
|
|
13
|
+
image: mongo:6
|
|
14
|
+
ports:
|
|
15
|
+
- 27017:27017
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout code
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Setup Node.js
|
|
22
|
+
uses: actions/setup-node@v4
|
|
23
|
+
with:
|
|
24
|
+
node-version: '20'
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm install
|
|
28
|
+
|
|
29
|
+
- name: Install grunt-cli
|
|
30
|
+
run: npm install -g grunt-cli
|
|
31
|
+
|
|
32
|
+
- name: Run linting
|
|
33
|
+
run: grunt
|
|
34
|
+
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: grunt test
|
|
37
|
+
|
|
38
|
+
publish-docker:
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
needs: test
|
|
41
|
+
|
|
42
|
+
steps:
|
|
43
|
+
- name: Checkout code
|
|
44
|
+
uses: actions/checkout@v4
|
|
45
|
+
|
|
46
|
+
- name: Extract version from package.json
|
|
47
|
+
id: version
|
|
48
|
+
run: |
|
|
49
|
+
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
|
50
|
+
MAJOR_VERSION=$(echo ${PACKAGE_VERSION} | awk -F. '{ print $1 }')
|
|
51
|
+
echo "PACKAGE_VERSION=${PACKAGE_VERSION}" >> $GITHUB_OUTPUT
|
|
52
|
+
echo "MAJOR_VERSION=${MAJOR_VERSION}" >> $GITHUB_OUTPUT
|
|
53
|
+
echo "Package version: ${PACKAGE_VERSION}"
|
|
54
|
+
echo "Major version: ${MAJOR_VERSION}"
|
|
55
|
+
|
|
56
|
+
- name: Set up Docker Buildx
|
|
57
|
+
uses: docker/setup-buildx-action@v3
|
|
58
|
+
|
|
59
|
+
- name: Login to Docker Hub
|
|
60
|
+
uses: docker/login-action@v3
|
|
61
|
+
with:
|
|
62
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
63
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
64
|
+
|
|
65
|
+
- name: Build and push Docker image
|
|
66
|
+
uses: docker/build-push-action@v5
|
|
67
|
+
with:
|
|
68
|
+
context: .
|
|
69
|
+
platforms: linux/amd64
|
|
70
|
+
push: true
|
|
71
|
+
tags: |
|
|
72
|
+
soajsorg/gateway:latest
|
|
73
|
+
soajsorg/gateway:${{ steps.version.outputs.PACKAGE_VERSION }}
|
|
74
|
+
soajsorg/gateway:${{ steps.version.outputs.MAJOR_VERSION }}.x
|
|
75
|
+
|
|
76
|
+
- name: Create Git tag
|
|
77
|
+
run: |
|
|
78
|
+
git config --local user.name "github-actions[bot]"
|
|
79
|
+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
80
|
+
git tag ${{ steps.version.outputs.PACKAGE_VERSION }} || true
|
|
81
|
+
|
|
82
|
+
- name: Push tag
|
|
83
|
+
run: git push origin ${{ steps.version.outputs.PACKAGE_VERSION }} || true
|
|
84
|
+
|
|
85
|
+
- name: Create GitHub Release
|
|
86
|
+
uses: softprops/action-gh-release@v1
|
|
87
|
+
with:
|
|
88
|
+
tag_name: ${{ steps.version.outputs.PACKAGE_VERSION }}
|
|
89
|
+
name: Release ${{ steps.version.outputs.PACKAGE_VERSION }}
|
|
90
|
+
generate_release_notes: true
|
|
91
|
+
env:
|
|
92
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# SOAJS Controller Gateway - System Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The SOAJS Controller is an API Gateway that serves as the central entry point for all microservices in the SOAJS ecosystem. It handles routing, service discovery, multi-tenant authentication, rate limiting, and request proxying.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
SOAJS Controller Gateway Architecture
|
|
9
|
+
=====================================
|
|
10
|
+
|
|
11
|
+
┌─────────────────────────────────────────────────────────────────────────────────────────┐
|
|
12
|
+
│ CLIENTS │
|
|
13
|
+
│ (Web Apps, Mobile Apps, External Services) │
|
|
14
|
+
└───────────────────────────────────────┬─────────────────────────────────────────────────┘
|
|
15
|
+
│
|
|
16
|
+
▼
|
|
17
|
+
┌─────────────────────────────────────────────────────────────────────────────────────────┐
|
|
18
|
+
│ SOAJS CONTROLLER GATEWAY │
|
|
19
|
+
│ (Port 4000) │
|
|
20
|
+
│ ┌───────────────────────────────────────────────────────────────────────────────────┐ │
|
|
21
|
+
│ │ MIDDLEWARE PIPELINE │ │
|
|
22
|
+
│ │ │ │
|
|
23
|
+
│ │ ┌─────────┐ ┌──────┐ ┌──────────┐ ┌─────────┐ ┌───────────┐ ┌───────────┐ │ │
|
|
24
|
+
│ │ │ SOAJS │─▶│ CORS │─▶│ Favicon │─▶│Response │─▶│ Enhancer │─▶│ IP2Ban │ │ │
|
|
25
|
+
│ │ │ Init │ │ │ │ │ │ Builder │ │ │ │ │ │ │
|
|
26
|
+
│ │ └─────────┘ └──────┘ └──────────┘ └─────────┘ └───────────┘ └───────────┘ │ │
|
|
27
|
+
│ │ │ │ │ │
|
|
28
|
+
│ │ ▼ ▼ │ │
|
|
29
|
+
│ │ ┌──────────────┐ ┌─────────┐ ┌───────────┐ ┌─────────┐ ┌───────────────┐ │ │
|
|
30
|
+
│ │ │ Maintenance │─▶│ URL │─▶│ Awareness │─▶│ Key │─▶│ Key ACL │ │ │
|
|
31
|
+
│ │ │ Mode │ │ Parser │ │ │ │ Loader │ │ Extractor │ │ │
|
|
32
|
+
│ │ └──────────────┘ └─────────┘ └───────────┘ └─────────┘ └───────────────┘ │ │
|
|
33
|
+
│ │ │ │ │
|
|
34
|
+
│ │ ▼ │ │
|
|
35
|
+
│ │ ┌──────────────┐ ┌─────────────┐ ┌─────────┐ ┌───────────────────────────┐ │ │
|
|
36
|
+
│ │ │ Traffic │◀─│ OAuth │◀─│ MT │◀─│ Goto Service │ │ │
|
|
37
|
+
│ │ │ (Throttle) │ │ (Auth) │ │(Tenant) │ │ (Route Selection) │ │ │
|
|
38
|
+
│ │ └──────────────┘ └─────────────┘ └─────────┘ └───────────────────────────┘ │ │
|
|
39
|
+
│ │ │ │ │
|
|
40
|
+
│ │ ▼ │ │
|
|
41
|
+
│ │ ┌──────────────┐ ┌─────────────────────────────────────────────────────────┐ │ │
|
|
42
|
+
│ │ │ Last Seen │─▶│ REQUEST HANDLER │ │ │
|
|
43
|
+
│ │ │ Tracker │ │ (Proxy to Target Service) │ │ │
|
|
44
|
+
│ │ └──────────────┘ └─────────────────────────────────────────────────────────┘ │ │
|
|
45
|
+
│ │ │ │
|
|
46
|
+
│ └───────────────────────────────────────────────────────────────────────────────────┘ │
|
|
47
|
+
│ │
|
|
48
|
+
│ ┌───────────────────────────────────────────────────────────────────────────────────┐ │
|
|
49
|
+
│ │ CORE MODULES │ │
|
|
50
|
+
│ │ │ │
|
|
51
|
+
│ │ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ ┌─────────────────┐ │ │
|
|
52
|
+
│ │ │ Registry │ │ Provision │ │ Awareness │ │ Driver │ │ │
|
|
53
|
+
│ │ │ Module │ │ Module │ │ Engine │ │ (K8s/Swarm) │ │ │
|
|
54
|
+
│ │ └────────────────┘ └────────────────┘ └────────────────┘ └─────────────────┘ │ │
|
|
55
|
+
│ │ │ │
|
|
56
|
+
│ └───────────────────────────────────────────────────────────────────────────────────┘ │
|
|
57
|
+
│ │
|
|
58
|
+
│ ┌───────────────────────────────────────────────────────────────────────────────────┐ │
|
|
59
|
+
│ │ MAINTENANCE SERVER (Port 5000) │ │
|
|
60
|
+
│ │ /heartbeat /loadProvision /reloadRegistry /awarenessStat │ │
|
|
61
|
+
│ └───────────────────────────────────────────────────────────────────────────────────┘ │
|
|
62
|
+
└─────────────────────────────────────────────────────────────────────────────────────────┘
|
|
63
|
+
│
|
|
64
|
+
┌───────────────────────────────┼───────────────────────────────┐
|
|
65
|
+
│ │ │
|
|
66
|
+
▼ ▼ ▼
|
|
67
|
+
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
|
|
68
|
+
│ MICROSERVICES │ │ DATA STORES │ │ EXTERNAL SERVICES │
|
|
69
|
+
│ │ │ │ │ │
|
|
70
|
+
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
|
|
71
|
+
│ │ Service A │ │ │ │ Core DB │ │ │ │ OAuth │ │
|
|
72
|
+
│ │ (v1, v2) │ │ │ │ (MongoDB) │ │ │ │ Service │ │
|
|
73
|
+
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
|
|
74
|
+
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
|
|
75
|
+
│ │ Service B │ │ │ │ Meta DB │ │ │ │ URAC │ │
|
|
76
|
+
│ │ (v1) │ │ │ │ (Tenant) │ │ │ │ Service │ │
|
|
77
|
+
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
|
|
78
|
+
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
|
|
79
|
+
│ │ Service C │ │ │ │ Throttle DB │ │ │ │ SOA Monitor │ │
|
|
80
|
+
│ │ (v1, v2) │ │ │ │ (Optional) │ │ │ │ Service │ │
|
|
81
|
+
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
|
|
82
|
+
│ │ │ │ │ │
|
|
83
|
+
└───────────────────┘ └───────────────────┘ └───────────────────┘
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Component Descriptions
|
|
89
|
+
|
|
90
|
+
### 1. Middleware Pipeline
|
|
91
|
+
|
|
92
|
+
The gateway processes requests through a sequential middleware pipeline:
|
|
93
|
+
|
|
94
|
+
| Order | Middleware | Responsibility | Documentation |
|
|
95
|
+
|-------|------------|----------------|---------------|
|
|
96
|
+
| 1 | **soajs** | Initializes `req.soajs` context, attaches registry, sets up logging | [soajs.md](docs/middleware/soajs.md) |
|
|
97
|
+
| 2 | **cors** | Handles CORS preflight (OPTIONS) and headers | [cors.md](docs/middleware/cors.md) |
|
|
98
|
+
| 3 | **favicon** | Serves favicon requests | [favicon.md](docs/middleware/favicon.md) |
|
|
99
|
+
| 4 | **response** | Adds `buildResponse()` and `controllerResponse()` helpers | [response.md](docs/middleware/response.md) |
|
|
100
|
+
| 5 | **enhancer** | Adds `req.get()` method for case-insensitive header retrieval | [enhancer.md](docs/middleware/enhancer.md) |
|
|
101
|
+
| 6 | **ip2ban** | Enforces IP blacklist from gateway configuration | [ip2ban.md](docs/middleware/ip2ban.md) |
|
|
102
|
+
| 7 | **maintenanceMode** | Returns 503 if gateway is in maintenance mode | [maintenanceMode.md](docs/middleware/maintenanceMode.md) |
|
|
103
|
+
| 8 | **url** | Parses URL into service name, version, and path components | [url.md](docs/middleware/url.md) |
|
|
104
|
+
| 9 | **awareness** | Initializes service discovery (getHost, getLatestVersion) | [awareness.md](docs/middleware/awareness.md) |
|
|
105
|
+
| 10 | **awarenessEnv** | Provides cross-environment awareness for roaming | - |
|
|
106
|
+
| 11 | **key** | Retrieves and validates external key from provision DB | [key.md](docs/middleware/key.md) |
|
|
107
|
+
| 12 | **keyACL** | Extracts ACL from tenant application or package | [keyACL.md](docs/middleware/keyACL.md) |
|
|
108
|
+
| 13 | **gotoService** | Determines routing strategy and validates service | [gotoService.md](docs/middleware/gotoService.md) |
|
|
109
|
+
| 14 | **mt** | Multi-tenant processing: security checks, URAC integration | [mt.md](docs/middleware/mt.md) |
|
|
110
|
+
| 15 | **oauth** | OAuth2 server authorization or JWT verification | [oauth.md](docs/middleware/oauth.md) |
|
|
111
|
+
| 16 | **traffic** | Rate limiting with public/private strategies | [traffic.md](docs/middleware/traffic.md) |
|
|
112
|
+
| 17 | **lastSeen** | Async notification to URAC for user activity tracking | [lastSeen.md](docs/middleware/lastSeen.md) |
|
|
113
|
+
|
|
114
|
+
### 2. Core Modules
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
┌─────────────────────────────────────────────────────────────────────────────────┐
|
|
118
|
+
│ CORE MODULES │
|
|
119
|
+
├─────────────────────────────────────────────────────────────────────────────────┤
|
|
120
|
+
│ │
|
|
121
|
+
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
|
122
|
+
│ │ REGISTRY MODULE │ │ PROVISION MODULE │ │
|
|
123
|
+
│ ├──────────────────────┤ ├──────────────────────┤ │
|
|
124
|
+
│ │ • Service definitions│ │ • Tenant management │ │
|
|
125
|
+
│ │ • Host mappings │ │ • Application data │ │
|
|
126
|
+
│ │ • Version configs │ │ • Key validation │ │
|
|
127
|
+
│ │ • Database configs │ │ • Package ACLs │ │
|
|
128
|
+
│ │ • Service configs │ │ • OAuth models │ │
|
|
129
|
+
│ │ • Custom gateway │ │ │ │
|
|
130
|
+
│ │ settings │ │ │ │
|
|
131
|
+
│ └──────────────────────┘ └──────────────────────┘ │
|
|
132
|
+
│ │
|
|
133
|
+
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
|
134
|
+
│ │ AWARENESS ENGINE │ │ DRIVER MODULE │ │
|
|
135
|
+
│ ├──────────────────────┤ ├──────────────────────┤ │
|
|
136
|
+
│ │ • Service discovery │ │ • Kubernetes client │ │
|
|
137
|
+
│ │ • Health tracking │ │ • Docker Swarm │ │
|
|
138
|
+
│ │ • Load balancing │ │ • Service lookups │ │
|
|
139
|
+
│ │ • Host resolution │ │ • Node management │ │
|
|
140
|
+
│ │ • Version resolution │ │ • Health monitoring │ │
|
|
141
|
+
│ └──────────────────────┘ └──────────────────────┘ │
|
|
142
|
+
│ │
|
|
143
|
+
└─────────────────────────────────────────────────────────────────────────────────┘
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Additional Documentation
|
|
149
|
+
|
|
150
|
+
| Document | Description |
|
|
151
|
+
|----------|-------------|
|
|
152
|
+
| [Request Flow](docs/request-flow.md) | Complete request lifecycle through the gateway |
|
|
153
|
+
| [Multi-Tenant Security](docs/multi-tenant-security.md) | Security pipeline and validation checks |
|
|
154
|
+
| [Service Discovery](docs/service-discovery.md) | Custom and HA service discovery modes |
|
|
155
|
+
| [Data Flow](docs/data-flow.md) | Database interactions and data flow |
|
|
156
|
+
| [External Integrations](docs/external-integrations.md) | OAuth, URAC, and infrastructure integrations |
|
|
157
|
+
| [Deployment Architecture](docs/deployment.md) | High availability deployment patterns |
|
|
158
|
+
| [Custom Registry Configuration](docs/configuration-custom-registry.md) | Environment-specific gateway settings |
|
|
159
|
+
| [Services Config](docs/configuration-services-config.md) | Tenant key-specific configuration |
|
|
160
|
+
| [Gateway Routes](docs/gateway-routes.md) | Built-in gateway routes (/soajs/acl, /soajs/proxy) |
|
|
161
|
+
| [Maintenance Routes](docs/maintenance-routes.md) | Health check and admin endpoints |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Key Files Reference
|
|
166
|
+
|
|
167
|
+
| File | Purpose |
|
|
168
|
+
|------|---------|
|
|
169
|
+
| `server/controller.js` | Main gateway orchestration |
|
|
170
|
+
| `server/maintenance.js` | Health check and admin server |
|
|
171
|
+
| `modules/registry/index.js` | Configuration loading and management |
|
|
172
|
+
| `modules/driver/index.js` | Infrastructure abstraction layer |
|
|
173
|
+
| `mw/key/index.js` | External key loading and validation |
|
|
174
|
+
| `mw/keyACL/index.js` | ACL extraction from key/package |
|
|
175
|
+
| `mw/gotoService/index.js` | Route selection and service discovery |
|
|
176
|
+
| `mw/mt/index.js` | Multi-tenant processing |
|
|
177
|
+
| `mw/traffic/index.js` | Rate limiting implementation |
|
|
178
|
+
| `lib/request.js` | HTTP proxy and request utilities |
|
|
179
|
+
| `utilities/utils.js` | Error handlers and utilities |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Summary
|
|
184
|
+
|
|
185
|
+
The SOAJS Controller Gateway is a comprehensive API Gateway solution that provides:
|
|
186
|
+
|
|
187
|
+
- **Multi-tenant Architecture**: Full isolation between tenants with configurable ACLs
|
|
188
|
+
- **Service Discovery**: Support for both static registry and dynamic HA modes (K8s/Swarm)
|
|
189
|
+
- **Security**: OAuth2/JWT authentication, IP whitelisting, geo-blocking, device fingerprinting
|
|
190
|
+
- **Traffic Management**: Configurable rate limiting with multiple storage backends
|
|
191
|
+
- **Request Proxying**: HTTP proxy with monitoring, timeout management, and heartbeat renewal
|
|
192
|
+
- **Observability**: Integration with monitoring services and comprehensive logging
|
|
193
|
+
- **High Availability**: Horizontal scaling with shared state in MongoDB
|
package/Gruntfile.js
CHANGED
|
@@ -246,7 +246,7 @@ module.exports = function (grunt) {
|
|
|
246
246
|
// When true, grunt-coveralls will only print a warning rather than
|
|
247
247
|
// an error, to prevent CI builds from failing unnecessarily (e.g. if
|
|
248
248
|
// coveralls.io is down). Optional, defaults to false.
|
|
249
|
-
force:
|
|
249
|
+
force: true
|
|
250
250
|
},
|
|
251
251
|
your_target: {
|
|
252
252
|
// Target-specific LCOV coverage file
|