Skip to content
This repository was archived by the owner on Sep 2, 2022. It is now read-only.

Commit c666c55

Browse files
authored
Merge pull request #4 from apilytics/apilytics-version
Send Apilytics version info together with metrics, create CD pipeline
2 parents bacc6e1 + ac38b88 commit c666c55

17 files changed

Lines changed: 3439 additions & 59 deletions

File tree

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint @typescript-eslint/no-var-requires: "off" */
21
const builtins = require('module').builtinModules.join('|');
32

43
module.exports = {
@@ -12,6 +11,7 @@ module.exports = {
1211
'@typescript-eslint/ban-ts-comment': 'off',
1312
'@typescript-eslint/no-empty-function': 'off',
1413
'@typescript-eslint/consistent-type-imports': 'error',
14+
'@typescript-eslint/no-var-requires': 'off',
1515
'no-return-await': 'error',
1616
'import/no-duplicates': 'error',
1717
'simple-import-sort/imports': [

.github/check_commits.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
22

3-
head="$(git remote show origin | awk '/HEAD branch/ {print $NF}')"
3+
head="$GITHUB_BASE_REF"
44
current="$(git rev-parse HEAD)"
55

66
if ! git merge-base --is-ancestor "origin/${head}" "$current"; then

.github/workflows/cd.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: "CD"
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
release-type:
7+
description: "Type of release?"
8+
required: true
9+
type: choice
10+
options:
11+
- patch
12+
- minor
13+
- major
14+
15+
jobs:
16+
release:
17+
name: "Release"
18+
if: ${{ github.ref == 'refs/heads/master' }}
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: "Checkout code"
22+
uses: actions/checkout@v2
23+
with:
24+
token: ${{ secrets.GH_PAT }}
25+
26+
- name: "Set up Node"
27+
uses: actions/setup-node@v2
28+
with:
29+
node-version: '12'
30+
cache: 'yarn'
31+
32+
- name: "Install dependencies"
33+
run: yarn install --frozen-lockfile
34+
35+
- name: "Build the sources"
36+
run: yarn build
37+
38+
- name: "Publish to npm"
39+
id: publish
40+
run: |
41+
yarn publish:all ${{ github.event.inputs.release-type }}
42+
echo "::set-output name=version::$(node --print 'require("./lerna.json").version')"
43+
env:
44+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
45+
46+
- name: "Update the changelog"
47+
# Find the first line that starts with `###` or `## [<number>` from the CHANGELOG and insert the new version header before it.
48+
run: |
49+
current_date="$(date -u '+%Y-%m-%d')"
50+
sed -i "0,/^\(###\|## *\[[0-9]\).*/{s//## [${{ steps.publish.outputs.version }}] - ${current_date}\n\n&/}" CHANGELOG.md
51+
52+
- name: "Extract version's changelog for release notes"
53+
# 1. Find the lines between the first `## [<number>` and the second `## [<number>`.
54+
# 2. Remove all leading and trailing newlines from the output.
55+
run: sed '1,/^## *\[[0-9]/d;/^## *\[[0-9]/Q' CHANGELOG.md | sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba' > release_notes.txt
56+
57+
- name: "Commit and tag the changes"
58+
uses: EndBug/add-and-commit@8c12ff729a98cfbcd3fe38b49f55eceb98a5ec02 # v7.5.0
59+
with:
60+
add: '["lerna.json", "*package.json", "CHANGELOG.md"]'
61+
message: 'Release ${{ steps.publish.outputs.version }}'
62+
tag: 'v${{ steps.publish.outputs.version }} --annotate --file /dev/null'
63+
default_author: github_actions
64+
pathspec_error_handling: exitImmediately
65+
66+
- name: "Create a GitHub release"
67+
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5 # v1
68+
with:
69+
tag_name: v${{ steps.publish.outputs.version }}
70+
name: v${{ steps.publish.outputs.version }}
71+
body_path: release_notes.txt

.github/workflows/ci.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ jobs:
2626

2727
linters:
2828
name: "Linters"
29-
needs: commits
30-
if: ${{ !failure() }}
3129
runs-on: ubuntu-latest
3230
steps:
3331
- name: "Checkout code"
@@ -47,8 +45,6 @@ jobs:
4745

4846
build:
4947
name: "Build"
50-
needs: commits
51-
if: ${{ !failure() }}
5248
runs-on: ubuntu-latest
5349
steps:
5450
- name: "Checkout code"
@@ -68,7 +64,6 @@ jobs:
6864

6965
tests:
7066
name: "Tests"
71-
if: ${{ !failure() }}
7267
needs: [linters, build]
7368
strategy:
7469
fail-fast: true

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Send Apilytics version info together with metrics.
13+
1014
## [1.0.1] - 2022-01-12
1115

16+
### Fixed
17+
18+
- Improve README documentation.
19+
1220
## [1.0.0] - 2022-01-11
1321

1422
### Added

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ Apilytics is a service that lets you analyze operational, performance and securi
1616

1717
2. Continue with installation directions for your specific framework:
1818

19-
- [**Express** (`@apilytics/express`)](./packages/express/README.md#installation)
19+
- [**Express** (`@apilytics/express`)](./packages/express#readme)
2020

21-
- [**Next.js** (`@apilytics/next`)](./packages/next/README.md#installation)
21+
- [**Next.js** (`@apilytics/next`)](./packages/next#readme)
2222

23-
- [**Other Node.js Frameworks** (`@apilytics/core`)](./packages/core/README.md#installation)
23+
- [**Other Node.js Frameworks** (`@apilytics/core`)](./packages/core#readme)

lerna.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"version": "1.0.1",
3+
"packages": ["packages/*"],
4+
"npmClient": "yarn",
5+
"useWorkspaces": true
6+
}

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
"packages/*"
55
],
66
"scripts": {
7-
"prebuild": "yarn --cwd=packages/core build",
8-
"build": "for dir in packages/*; do echo \"$dir\" && yarn --cwd=\"$dir\" build; done",
9-
"clean": "for dir in packages/*; do echo \"$dir\" && yarn --cwd=\"$dir\" clean; done",
7+
"build": "lerna run build",
8+
"clean": "lerna run clean",
9+
"publish:all": "lerna publish --force-publish='*' --exact --no-git-tag-version --yes",
1010
"format": "prettier --write '**/*.{ts,js,json}' && eslint --fix --max-warnings=0 --ext=.ts,.js .",
1111
"lint": "prettier --check '**/*.{ts,js,json}' && eslint --max-warnings=0 --ext=.ts,.js .",
1212
"type-check": "yarn tsc --noEmit",
1313
"test": "jest --verbose",
1414
"test:cov": "yarn test --coverage",
15-
"postinstall": "yarn prebuild"
15+
"postinstall": "yarn --cwd=packages/core build"
1616
},
1717
"devDependencies": {
1818
"@types/jest": "27.4.0",
@@ -23,6 +23,7 @@
2323
"eslint-plugin-import": "2.25.4",
2424
"eslint-plugin-simple-import-sort": "7.0.0",
2525
"jest": "27.4.7",
26+
"lerna": "4.0.0",
2627
"prettier": "2.5.1",
2728
"supertest": "6.1.6",
2829
"ts-jest": "27.1.2",

packages/core/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Apilytics is a service that lets you analyze operational, performance and securi
1212

1313
Make sure to check out our out-of-the-box middleware packages first:
1414

15-
- [**Express** (`@apilytics/express`)](../express/README.md#installation)
15+
- [**Express** (`@apilytics/express`)](../express#readme)
1616

17-
- [**Next.js** (`@apilytics/next`)](../next/README.md#installation)
17+
- [**Next.js** (`@apilytics/next`)](../next#readme)
1818

1919
## Installation
2020

packages/core/__tests__/index.test.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@ import type http from 'http';
33

44
import { milliSecondTimer, sendApilyticsMetrics } from '../src';
55

6+
const APILYTICS_VERSION = require('../package.json').version;
7+
68
describe('sendApilyticsMetrics()', () => {
79
const OLD_ENV = process.env;
10+
const apiKey = 'dummy-key';
811

912
const params = {
10-
apiKey: 'dummy-key',
13+
apiKey,
1114
path: '/',
1215
method: 'GET',
1316
statusCode: 200,
1417
timeMillis: 10,
1518
};
1619

1720
let consoleErrorSpy: jest.SpyInstance;
21+
let requestSpy: jest.SpyInstance;
1822

1923
const clientRequestMock = {
2024
on: jest.fn().mockImplementation((event, handler) => {
@@ -28,7 +32,7 @@ describe('sendApilyticsMetrics()', () => {
2832
jest.resetModules();
2933
process.env = { ...OLD_ENV };
3034

31-
jest
35+
requestSpy = jest
3236
.spyOn(https, 'request')
3337
.mockImplementation(
3438
() => clientRequestMock as unknown as http.ClientRequest,
@@ -46,6 +50,64 @@ describe('sendApilyticsMetrics()', () => {
4650
process.env = OLD_ENV;
4751
});
4852

53+
it('should call apilytics API', async () => {
54+
sendApilyticsMetrics(params);
55+
56+
expect(requestSpy).toHaveBeenCalledTimes(1);
57+
58+
expect(APILYTICS_VERSION).toBeTruthy();
59+
expect(process.versions.node).toBeTruthy();
60+
61+
expect(requestSpy).toHaveBeenLastCalledWith({
62+
hostname: 'www.apilytics.io',
63+
port: 443,
64+
path: '/api/v1/middleware',
65+
method: 'POST',
66+
headers: {
67+
'Content-Type': 'application/json',
68+
'Content-Length': expect.any(Number),
69+
'X-API-Key': apiKey,
70+
'Apilytics-Version': `apilytics-node-core/${APILYTICS_VERSION};node/${process.versions.node}`,
71+
},
72+
});
73+
74+
expect(clientRequestMock.on).toHaveBeenCalledTimes(1);
75+
expect(clientRequestMock.write).toHaveBeenCalledTimes(1);
76+
expect(clientRequestMock.end).toHaveBeenCalledTimes(1);
77+
78+
const data = JSON.parse(clientRequestMock.write.mock.calls[0]);
79+
expect(data).toStrictEqual({
80+
path: '/',
81+
method: 'GET',
82+
statusCode: 200,
83+
timeMillis: expect.any(Number),
84+
});
85+
expect(data['timeMillis']).toEqual(Math.trunc(data['timeMillis']));
86+
});
87+
88+
it('should allow to pass optional `apilyticsIntegration` and `integratedLibrary` params', async () => {
89+
sendApilyticsMetrics({
90+
...params,
91+
apilyticsIntegration: 'dummy',
92+
integratedLibrary: 'lib/1.2.3',
93+
});
94+
95+
expect(requestSpy).toHaveBeenCalledTimes(1);
96+
97+
expect(requestSpy).toHaveBeenLastCalledWith({
98+
hostname: 'www.apilytics.io',
99+
port: 443,
100+
path: '/api/v1/middleware',
101+
method: 'POST',
102+
headers: {
103+
'Content-Type': 'application/json',
104+
'Content-Length': expect.any(Number),
105+
'X-API-Key': apiKey,
106+
'Apilytics-Version': `dummy/${APILYTICS_VERSION};node/${process.versions.node};lib/1.2.3`,
107+
},
108+
});
109+
});
110+
49111
it('should hide HTTP errors in production', async () => {
50112
// @ts-ignore: Assigning to a read-only property.
51113
process.env.NODE_ENV = 'production';

0 commit comments

Comments
 (0)