@voiceflow/danger-config 1.1.0

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/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Danger Config
2
+
3
+ Shared pull request rules for [`danger`](https://danger.systems/js/), so PRs have what `voiceflow/changelog` needs:
4
+
5
+ - a `## Summary` of at least 40 characters
6
+ - a Linear ticket in the title or branch name
7
+ - an `## Affected routes` section when a NestJS controller changes, listing the endpoints whose behaviour changes, or `None`
8
+ - an `## Affected actions and channels` section when a Logux controller changes, listing the actions and channels whose behaviour changes, or `None`
9
+ - an `## Affected pages` section when a file under `apps/*/src/**/pages/` changes, listing the pages whose behaviour or UI changes, or `None`
10
+ - a `## Feature flags` section when changed lines reference `FeatureFlag.*` or a flag definition file changes, listing the flags whose gates change, or `None`
11
+
12
+ ## Installation
13
+
14
+ ```sh
15
+ yarn add --exact -D danger @voiceflow/danger-config
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ danger only provides its globals inside the dangerfile, so pass them in:
21
+
22
+ ```ts
23
+ // dangerfile.ts
24
+ import { danger, fail, schedule, warn } from 'danger';
25
+
26
+ import { runDangerRules } from '@voiceflow/danger-config';
27
+
28
+ schedule(runDangerRules({ danger, fail, warn }, { ticketExample: 'COR-123' }));
29
+ ```
30
+
31
+ | Option | Default | Description |
32
+ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
33
+ | `ticketExample` | `ENG-123` | ticket used in messages |
34
+ | `minSummaryLength` | `40` | characters the `## Summary` section needs |
35
+ | `sourceFilePattern` | `^(apps\|libs)/*/src/**.tsx?` | changed files the route, Logux, page and flag rules read, tests are excluded |
36
+ | `routes` | `{ controllerFilePattern: apps/*/src/**.controller.ts }`, without `*.logux.controller.ts` | controllers that need `## Affected routes`, `false` turns it off |
37
+ | `logux` | `{ controllerFilePattern: apps/*/src/**.logux.controller.ts }` | Logux controllers that need `## Affected actions and channels`, `false` turns it off |
38
+ | `pages` | `{ pageFilePattern: apps/*/src/**/pages/** }` | pages that need `## Affected pages`, `false` turns it off |
39
+ | `featureFlags` | `{ referencePattern: /\bFeatureFlag\s*\./, definitionFilePattern: **/feature-flag.enum.ts, **/feature-flags/index.ts, **/config/features.ts }` | changed lines or definition files that need `## Feature flags`, `false` turns it off |
40
+
41
+ ### GitHub workflow
42
+
43
+ danger only needs itself, `typescript` and this package, so the workflow can skip installing the repository. The dangerfile runs as an ES module, which doesn't read `NODE_PATH`, so link the package into `node_modules`:
44
+
45
+ ```yaml
46
+ - name: Install danger
47
+ run: |
48
+ version() { node -p "require('./package.json').devDependencies['$1']"; }
49
+ npm install --prefix "$RUNNER_TEMP/danger" --no-save --no-audit --no-fund \
50
+ "danger@$(version danger)" "typescript@$(version typescript)" "@voiceflow/danger-config@$(version @voiceflow/danger-config)"
51
+ mkdir -p node_modules/@voiceflow
52
+ ln -s "$RUNNER_TEMP/danger/node_modules/@voiceflow/danger-config" node_modules/@voiceflow/danger-config
53
+
54
+ - name: Run danger
55
+ run: '"$RUNNER_TEMP/danger/node_modules/.bin/danger" ci --dangerfile dangerfile.ts'
56
+ env:
57
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58
+ ```
@@ -0,0 +1,12 @@
1
+ export declare const SUMMARY_SECTION = "Summary";
2
+ export declare const FLAGS_SECTION = "Feature flags";
3
+ export declare const ROUTES_SECTION = "Affected routes";
4
+ export declare const PAGES_SECTION = "Affected pages";
5
+ export declare const LOGUX_SECTION = "Affected actions and channels";
6
+ /**
7
+ * the description's sections by lowercased heading, without template comments or subheadings,
8
+ * a section includes its subsections, text before the first heading is under an empty heading
9
+ */
10
+ export declare const parseSections: (body: string) => Map<string, string>;
11
+ export declare const getSection: (sections: Map<string, string>, heading: string) => string | null;
12
+ //# sourceMappingURL=description.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"description.d.ts","sourceRoot":"","sources":["../src/description.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,YAAY,CAAC;AACzC,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAC7C,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAChD,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAC9C,eAAO,MAAM,aAAa,kCAAkC,CAAC;AAK7D;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAiB9D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,MAAM,kBAC5B,CAAC"}
@@ -0,0 +1,29 @@
1
+ export const SUMMARY_SECTION = 'Summary';
2
+ export const FLAGS_SECTION = 'Feature flags';
3
+ export const ROUTES_SECTION = 'Affected routes';
4
+ export const PAGES_SECTION = 'Affected pages';
5
+ export const LOGUX_SECTION = 'Affected actions and channels';
6
+ const HEADING_PATTERN = /^(#{1,6})\s+(.+?)\s*#*\s*$/;
7
+ const COMMENT_PATTERN = /<!--[\s\S]*?-->/g;
8
+ /**
9
+ * the description's sections by lowercased heading, without template comments or subheadings,
10
+ * a section includes its subsections, text before the first heading is under an empty heading
11
+ */
12
+ export const parseSections = (body) => {
13
+ const sections = new Map([['', []]]);
14
+ // the sections the current line belongs to, any heading closes the text before the first one
15
+ let open = [{ level: Infinity, lines: sections.get('') }];
16
+ for (const line of body.replace(COMMENT_PATTERN, '').split(/\r?\n/)) {
17
+ const [, hashes, heading] = line.match(HEADING_PATTERN) ?? [];
18
+ if (hashes && heading) {
19
+ const lines = [];
20
+ sections.set(heading.toLowerCase(), lines);
21
+ open = [...open.filter(({ level }) => level < hashes.length), { level: hashes.length, lines }];
22
+ continue;
23
+ }
24
+ open.forEach(({ lines }) => lines.push(line));
25
+ }
26
+ return new Map([...sections].map(([heading, lines]) => [heading, lines.join('\n').trim()]));
27
+ };
28
+ export const getSection = (sections, heading) => sections.get(heading.toLowerCase()) ?? null;
29
+ //# sourceMappingURL=description.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"description.js","sourceRoot":"","sources":["../src/description.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAChD,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAC;AAC9C,MAAM,CAAC,MAAM,aAAa,GAAG,+BAA+B,CAAC;AAE7D,MAAM,eAAe,GAAG,4BAA4B,CAAC;AACrD,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAuB,EAAE;IACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAmB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,6FAA6F;IAC7F,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAE,EAAE,CAAC,CAAC;IAE3D,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACpE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;QAC9D,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;YACtB,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;YAC3C,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/F,SAAS;QACX,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAA6B,EAAE,OAAe,EAAE,EAAE,CAC3E,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { DangerDSLType } from 'danger';
2
+ /**
3
+ * the globals danger injects into a dangerfile, which only exist there, so they're passed in
4
+ */
5
+ export interface DangerGlobals {
6
+ danger: DangerDSLType;
7
+ fail: (message: string) => void;
8
+ warn: (message: string) => void;
9
+ }
10
+ export interface DangerRulesOptions {
11
+ /** the ticket the messages use as an example, e.g. `ENG-123` */
12
+ ticketExample?: string;
13
+ /** characters the `## Summary` section needs */
14
+ minSummaryLength?: number;
15
+ /** the changed files the flag, route, logux and page rules read, test files are always left out */
16
+ sourceFilePattern?: RegExp;
17
+ /** changed controllers need an `## Affected routes` section, `false` turns the rule off */
18
+ routes?: {
19
+ controllerFilePattern?: RegExp;
20
+ } | false;
21
+ /** changed logux controllers need an `## Affected actions and channels` section, `false` turns the rule off */
22
+ logux?: {
23
+ controllerFilePattern?: RegExp;
24
+ } | false;
25
+ /** changed pages need an `## Affected pages` section, `false` turns the rule off */
26
+ pages?: {
27
+ pageFilePattern?: RegExp;
28
+ } | false;
29
+ /** changed lines that reference a flag, or changed flag definitions, need a `## Feature flags` section, `false` turns the rule off */
30
+ featureFlags?: {
31
+ referencePattern?: RegExp;
32
+ definitionFilePattern?: RegExp;
33
+ } | false;
34
+ }
35
+ /**
36
+ * checks the PR has what voiceflow/changelog needs, call it from the dangerfile:
37
+ * `schedule(runDangerRules({ danger, fail, warn }, options))`
38
+ */
39
+ export declare const runDangerRules: ({ danger, fail, warn }: DangerGlobals, options?: DangerRulesOptions) => Promise<void>;
40
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAoB5C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mGAAmG;IACnG,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2FAA2F;IAC3F,MAAM,CAAC,EAAE;QAAE,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACpD,+GAA+G;IAC/G,KAAK,CAAC,EAAE;QAAE,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACnD,oFAAoF;IACpF,KAAK,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IAC7C,sIAAsI;IACtI,YAAY,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;CACtF;AAeD;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAU,wBAAwB,aAAa,EAAE,UAAS,kBAAuB,kBAiG3G,CAAC"}
package/build/main.js ADDED
@@ -0,0 +1,90 @@
1
+ import { FLAGS_SECTION, getSection, LOGUX_SECTION, PAGES_SECTION, parseSections, ROUTES_SECTION, SUMMARY_SECTION, } from './description.js';
2
+ // voiceflow/changelog writes what shipped from the PR's summary, ticket, feature flags, routes, Logux actions and pages
3
+ // e.g. `(ENG-123)` in the title or `ben/eng-123` as the branch
4
+ const TITLE_TICKET_PATTERN = /\(([A-Z][A-Z0-9]*)-(\d+)\)/;
5
+ const BRANCH_TICKET_PATTERN = /(?:^|\/)([a-z][a-z0-9]*)-(\d+)$/i;
6
+ const RELEASE_TITLE_PATTERN = /^chore\(release\)/i;
7
+ const TEST_FILE_PATTERN = /\.(?:test|spec|fixtures?|mocks?|stories)\.tsx?$|\/__(?:tests|mocks|fixtures)__\//;
8
+ const DEFAULT_OPTIONS = {
9
+ ticketExample: 'ENG-123',
10
+ minSummaryLength: 40,
11
+ sourceFilePattern: /^(?:apps|libs)\/[^/]+\/src\/.+\.tsx?$/,
12
+ // logux controllers handle actions, not HTTP routes
13
+ controllerFilePattern: /^apps\/[^/]+\/src\/(?!.*\.logux\.controller\.ts$).*\.controller\.ts$/,
14
+ loguxControllerFilePattern: /^apps\/[^/]+\/src\/.*\.logux\.controller\.ts$/,
15
+ pageFilePattern: /^apps\/[^/]+\/src\/(?:.+\/)?pages\//,
16
+ referencePattern: /\bFeatureFlag\s*\./,
17
+ // e.g. `feature-flag/feature-flag.enum.ts`, `feature-flags/index.ts` or `config/features.ts`
18
+ definitionFilePattern: /(?:\/feature-flags?\/index|feature-flag\.enum|\/config\/features)\.ts$/,
19
+ };
20
+ /**
21
+ * checks the PR has what voiceflow/changelog needs, call it from the dangerfile:
22
+ * `schedule(runDangerRules({ danger, fail, warn }, options))`
23
+ */
24
+ export const runDangerRules = async ({ danger, fail, warn }, options = {}) => {
25
+ const { ticketExample, minSummaryLength, sourceFilePattern } = { ...DEFAULT_OPTIONS, ...options };
26
+ const { pr } = danger.github;
27
+ const sections = parseSections(pr.body ?? '');
28
+ const sourceFiles = [...danger.git.created_files, ...danger.git.modified_files, ...danger.git.deleted_files].filter((file) => sourceFilePattern.test(file) && !TEST_FILE_PATTERN.test(file));
29
+ const hasSection = (heading) => !!getSection(sections, heading);
30
+ const checkDescription = () => {
31
+ const summary = getSection(sections, SUMMARY_SECTION) ?? getSection(sections, '') ?? '';
32
+ if (summary.length >= minSummaryLength)
33
+ return;
34
+ fail(`Describe what this PR changes for users or integrators and why under \`## ${SUMMARY_SECTION}\`, the changelog is written from it. It needs at least ${minSummaryLength} characters.`);
35
+ };
36
+ const checkTicket = () => {
37
+ const ticket = pr.title.match(TITLE_TICKET_PATTERN) ?? pr.head.ref.match(BRANCH_TICKET_PATTERN);
38
+ if (!ticket || Number(ticket[2]) === 0) {
39
+ warn(`Add a Linear ticket to the title, e.g. \`feat: add thing (${ticketExample})\`, or to the branch name, e.g. \`ben/${ticketExample.toLowerCase()}\`. The changelog groups changes by ticket.`);
40
+ }
41
+ };
42
+ const changesReference = async (file, pattern) => {
43
+ const diff = await danger.git.structuredDiffForFile(file);
44
+ return (diff?.chunks ?? []).some(({ changes }) => changes.some(({ type, content }) => type !== 'normal' && pattern.test(content)));
45
+ };
46
+ const checkFeatureFlags = async (referencePattern, definitionFilePattern) => {
47
+ if (hasSection(FLAGS_SECTION))
48
+ return;
49
+ if (sourceFiles.some((file) => definitionFilePattern.test(file))) {
50
+ fail(`This PR changes feature flag definitions, list each flag it adds, changes or removes under \`## ${FLAGS_SECTION}\` with what it gates and whether it's on anywhere yet, or write \`None\`.`);
51
+ return;
52
+ }
53
+ const changed = await Promise.all(sourceFiles.map((file) => changesReference(file, referencePattern)));
54
+ if (!changed.includes(true))
55
+ return;
56
+ fail(`This PR changes code that references feature flags, list each flag it adds, changes or removes a gate for under \`## ${FLAGS_SECTION}\` with what it gates and whether it's on anywhere yet, or write \`None\`.`);
57
+ };
58
+ const checkRoutes = (controllerFilePattern) => {
59
+ if (hasSection(ROUTES_SECTION) || !sourceFiles.some((file) => controllerFilePattern.test(file)))
60
+ return;
61
+ fail(`This PR changes controllers, list each endpoint whose behaviour changes under \`## ${ROUTES_SECTION}\`, e.g. \`GET /workspace/:workspaceID\`, or write \`None\`.`);
62
+ };
63
+ const checkLogux = (controllerFilePattern) => {
64
+ if (hasSection(LOGUX_SECTION) || !sourceFiles.some((file) => controllerFilePattern.test(file)))
65
+ return;
66
+ fail(`This PR changes logux controllers, list each action or channel whose behaviour changes under \`## ${LOGUX_SECTION}\`, e.g. \`Actions.APITool.CreateOne\`, or write \`None\`.`);
67
+ };
68
+ const checkPages = (pageFilePattern) => {
69
+ if (hasSection(PAGES_SECTION) || !sourceFiles.some((file) => pageFilePattern.test(file)))
70
+ return;
71
+ fail(`This PR changes pages, list each page whose behaviour or UI changes under \`## ${PAGES_SECTION}\`, e.g. \`Canvas\`, or write \`None\`.`);
72
+ };
73
+ if (pr.user.type === 'Bot' || RELEASE_TITLE_PATTERN.test(pr.title))
74
+ return;
75
+ checkDescription();
76
+ checkTicket();
77
+ if (options.featureFlags !== false) {
78
+ await checkFeatureFlags(options.featureFlags?.referencePattern ?? DEFAULT_OPTIONS.referencePattern, options.featureFlags?.definitionFilePattern ?? DEFAULT_OPTIONS.definitionFilePattern);
79
+ }
80
+ if (options.routes !== false) {
81
+ checkRoutes(options.routes?.controllerFilePattern ?? DEFAULT_OPTIONS.controllerFilePattern);
82
+ }
83
+ if (options.logux !== false) {
84
+ checkLogux(options.logux?.controllerFilePattern ?? DEFAULT_OPTIONS.loguxControllerFilePattern);
85
+ }
86
+ if (options.pages !== false) {
87
+ checkPages(options.pages?.pageFilePattern ?? DEFAULT_OPTIONS.pageFilePattern);
88
+ }
89
+ };
90
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@voiceflow/danger-config",
3
+ "version": "1.1.0",
4
+ "files": [
5
+ "build"
6
+ ],
7
+ "type": "module",
8
+ "main": "build/main.js",
9
+ "types": "build/main.d.ts",
10
+ "scripts": {
11
+ "build": "yarn g:build:pkg",
12
+ "clean": "yarn g:rimraf build",
13
+ "lint": "yarn g:run-p -c lint:oxlint lint:oxfmt",
14
+ "lint:oxlint": "yarn g:oxlint",
15
+ "lint:fix": "yarn g:run-p -c \"lint:oxlint --fix\" \"lint:oxfmt --write\"",
16
+ "lint:oxfmt": "yarn g:oxfmt --check",
17
+ "tdd": "vitest run --watch",
18
+ "test": "yarn g:run-p -c test:types test:unit test:cycles test:unused",
19
+ "test:cycles": "yarn g:dpdm src/main.ts",
20
+ "test:types": "yarn g:tsc --noEmit",
21
+ "test:unit": "yarn g:vitest run --coverage",
22
+ "test:unused": "yarn g:knip --workspace @voiceflow/danger-config"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "26.2.0",
26
+ "@voiceflow/tsconfig": "1.18.0",
27
+ "@voiceflow/vitest-config": "1.16.0",
28
+ "danger": "14.0.7"
29
+ },
30
+ "peerDependencies": {
31
+ "danger": "^14"
32
+ },
33
+ "engines": {
34
+ "node": "26"
35
+ },
36
+ "volta": {
37
+ "extends": "../../package.json"
38
+ },
39
+ "gitHead": "6942bea4a033116fccdd8954af01ef46f1bc7634"
40
+ }