### Setup Danger JS Project
Source: https://github.com/danger/danger-js/blob/main/CONTRIBUTING.md
Clone the repository, install dependencies using Yarn, and verify the installation by running tests and linters.
```sh
git clone https://github.com/danger/danger-js.git
cd danger-js
# if you don't have yarn installed
npm install -g yarn
yarn install
```
```sh
yarn test
yarn lint
```
--------------------------------
### Check README for Missing CI Providers
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-library.html.md
This example checks if all supported CI providers are listed in the README.md file. It reads the README, gets the names of CI providers from the Danger library's internal configuration, and warns if any are missing from the README.
```javascript
import { danger, fail, warn } from "danger"
import contains from "lodash.contains"
// This is a list of all the CI providers
import { realProviders } from "./source/ci_source/providers"
const readme = fs.readFileSync("README.md", "utf8")
const names = realProviders.map(ci => new ci({}).name)
const missing = names.filter(name => !contains(readme, name))
if (missing.length) {
warn(`These providers are missing from the README: ${sentence(missing.length)}`)
}
```
--------------------------------
### Install Danger JS Dependencies
Source: https://github.com/danger/danger-js/blob/main/README.md
Clone the repository, navigate to the directory, and install dependencies using Yarn. Ensure Yarn is installed globally.
```sh
git clone https://github.com/danger/danger-js.git
cd danger-js
# if you don't have yarn installed
npm install -g yarn
yarn install
```
--------------------------------
### Start Danger Plugin Project with Yeoman
Source: https://github.com/danger/danger-js/blob/main/docs/usage/extending-danger.html.md
Initiates the Danger plugin creation process using the installed Yeoman generator. Follow the prompts to configure your new plugin.
```sh
yo danger-plugin
```
--------------------------------
### Install Danger and Husky
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/fast-feedback.html.md
Add Danger and husky as development dependencies to your project.
```sh
yarn add --dev danger husky
```
--------------------------------
### CI Script Example
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-app.html.md
Example of CI script commands including Danger CI execution.
```yaml
script:
- yarn lint
- yarn test
- yarn danger ci
```
--------------------------------
### Install Danger JS
Source: https://github.com/danger/danger-js/blob/main/docs/usage/danger-process.html.md
Instructions for installing Danger JS using Homebrew and npm. This is typically done on a Mac environment.
```bash
brew install node
npm install -g danger
```
--------------------------------
### Configure Husky Pre-push Hook
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/fast-feedback.html.md
Set up a pre-push hook in your `package.json` to run Danger locally before code is pushed. This example uses a `prepush` script to build the project and then run `danger local`.
```json
"scripts": {
"prepush": "yarn build; yarn danger:prepush",
"danger:prepush": "yarn danger local --dangerfile dangerfile.lite.ts"
// [...]
}
```
--------------------------------
### Example Danger Plugin Structure
Source: https://github.com/danger/danger-js/blob/main/docs/usage/extending-danger.html.md
Illustrates the typical directory structure generated for a Danger plugin project, including source files, tests, and configuration.
```sh
$ tree danger-plugin-yarn
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── package.json
├── src
│ ├── index.test.ts
│ └── index.ts
├── tsconfig.json
├── tslint.json
└── yarn.lock
```
--------------------------------
### Start Dangerfile Evaluation
Source: https://github.com/danger/danger-js/blob/main/docs/usage/danger-process.html.md
Instantiates and runs a Dangerfile using the Dangerfile.new runtime. This is the primary method for executing Danger code.
```ruby
runtime = Dangerfile.new
runtime.run
```
--------------------------------
### Install Yeoman Generator for Danger Plugins
Source: https://github.com/danger/danger-js/blob/main/docs/usage/extending-danger.html.md
Installs the Yeoman generator and Danger plugin template globally. This is the first step to scaffolding a new Danger plugin.
```sh
npm i -g yo generator-danger-plugin
```
--------------------------------
### Run Danger JS Tests and Linters
Source: https://github.com/danger/danger-js/blob/main/README.md
Verify your Danger JS installation by running the test suite and linters. Fixers for tslint and prettier are applied on commit.
```sh
yarn test
yarn lint
```
--------------------------------
### Match Files with Danger JS
Source: https://github.com/danger/danger-js/blob/main/docs/guides/the_dangerfile.html.md
Use `danger.git.fileMatch` to create patterns for files you are interested in. This example shows how to check for modified documentation files and app files without corresponding tests.
```js
import { danger } from "danger"
const docs = danger.git.fileMatch("**/*.md")
const app = danger.git.fileMatch("src/**/*.ts")
const tests = danger.git.fileMatch("*/__tests__/*")
if (docs.edited) {
message("Thanks - We :heart: our [documentarians](http://www.writethedocs.org/)")
}
if (app.modified && !tests.modified) {
warn("You have app changes without tests.")
}
```
--------------------------------
### Warn on Missing CHANGELOG for Library Changes
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-library.html.md
This rule is more specific than the previous one. It warns if there are changes to the library's source code (files starting with 'lib/') but no corresponding CHANGELOG.md entry. This avoids unnecessary warnings for non-code changes.
```javascript
import { danger, fail, warn } from "danger"
import first from "lodash.first"
const changelogChanges = danger.git.fileMatch("CHANGELOG.md")
const hasLibraryChanges = first(danger.git.modified_files, path => path.startsWith("lib/"))
if (hasLibraryChanges && !changelogChanges.modified) {
warn("This pull request may need a CHANGELOG entry.")
}
```
--------------------------------
### Configure Proxy for Debugging with Danger JS
Source: https://github.com/danger/danger-js/blob/main/docs/usage/bitbucket_server.html.md
Shows how to set environment variables to configure an HTTP or HTTPS proxy for debugging requests, useful for inspecting traffic.
```bash
export NODE_TLS_REJECT_UNAUTHORIZED=0 # Avoid certificate error
export http_proxy=http://127.0.0.1:8080
or
export https_proxy=https://127.0.0.1:8080
```
--------------------------------
### Preview Danger DSL as JSON
Source: https://github.com/danger/danger-js/blob/main/docs/usage/danger-process.html.md
Use the `--js` and `--json` flags with `danger pr` to preview the Danger DSL that will be sent to your custom process. This is useful for understanding the data structure and for generating data fixtures.
```sh
danger pr https://github.com/danger/danger-js/pull/395 --js
```
```sh
danger pr https://github.com/danger/danger-js/pull/395 --json > danger-js-395.dsl.json
```
--------------------------------
### Build List for Unknown Files
Source: https://github.com/danger/danger-js/blob/main/source/platforms/gitlab/_tests/fixtures/fileContentsBefore.txt
This function formats a list of filenames. If the list exceeds 10 items, it is enclosed in a collapsible details tag for better readability.
```ruby
def build_list(items)
list = items.map { |filename| "* `#{filename}`" }.join("\n")
if items.size > 10
"\n\n\n#{list}\n\n "
else
list
end
end
```
--------------------------------
### Danger JS BitBucket Server DSL Overview
Source: https://github.com/danger/danger-js/blob/main/docs/usage/bitbucket_server.html.md
Illustrates the available properties within the `danger.bitbucket_server` object for interacting with BitBucket Server data.
```typescript
danger.bitbucket_server.
/** The pull request and repository metadata */
metadata: RepoMetaData
/** The related JIRA issues */
issues: JIRAIssue[]
/** The PR metadata */
pr: BitBucketServerPRDSL
/** The commits associated with the pull request */
commits: BitBucketServerCommit[]
/** The comments on the pull request */
comments: BitBucketServerPRActivity[]
/** The activities such as OPENING, CLOSING, MERGING or UPDATING a pull request */
activities: BitBucketServerPRActivity[]
```
--------------------------------
### Simulate CI Environment Locally
Source: https://github.com/danger/danger-js/blob/main/docs/guides/the_dangerfile.html.md
Use these environment variables to fake a CI environment for local testing. This allows you to run Danger against a specific pull request on your local machine.
```bash
export DANGER_FAKE_CI="YEP"
export DANGER_TEST_REPO='username/reponame'
```
```bash
git checkout branch-for-pr-1234
DANGER_TEST_PR='1234' yarn danger ci
```
--------------------------------
### Configure API Authentication Tokens
Source: https://github.com/danger/danger-js/blob/main/docs/guides/the_dangerfile.html.md
Set these environment variables to authenticate API requests for private repositories or to avoid rate limits. Different variables are available for GitHub, BitBucket Server, and BitBucket Cloud.
```sh
export DANGER_GITHUB_API_TOKEN='xxxx'
```
```sh
export DANGER_BITBUCKETSERVER_HOST='xxxx' DANGER_BITBUCKETSERVER_USERNAME='yyyy' DANGER_BITBUCKETSERVER_PASSWORD='zzzz'
```
```sh
export DANGER_BITBUCKETSERVER_HOST='xxxx' DANGER_BITBUCKETSERVER_USERNAME='yyyy' DANGER_BITBUCKETSERVER_TOKEN='zzzz'
```
```sh
export DANGER_BITBUCKETCLOUD_USERNAME='xxxx'
export DANGER_BITBUCKETCLOUD_PASSWORD='yyyy'
```
```sh
# You can get OAuth key from Settings > OAuth > Add consumer, put `https://bitbucket.org/site/oauth2/authorize` for `Callback URL`, and enable Read Pull requests, and Read Account Permissions.
export DANGER_BITBUCKETCLOUD_OAUTH_KEY='xxxx'
export DANGER_BITBUCKETCLOUD_OAUTH_SECRET='yyyy'
```
```sh
# You can get a Repository Access Token from Repo Settings > Security > Acesss Tokens and set Pull requests write scope.
export DANGER_BITBUCKETCLOUD_REPO_ACCESSTOKEN='xxxx'
```
--------------------------------
### Enable Debug Logging for Danger
Source: https://github.com/danger/danger-js/blob/main/docs/guides/faq.html.md
Prefix Danger commands with DEBUG="*" to enable verbose logging, which is helpful for understanding Danger's internal processes.
```sh
DEBUG="*" DANGER_GITHUB_API_TOKEN=[123] yarn danger pr https://github.com/facebook/react/pull/11865
```
```sh
DEBUG="*" yarn danger ci
```
--------------------------------
### Troubleshooting STDIN Timeout
Source: https://github.com/danger/danger-js/blob/main/docs/usage/danger-process.html.md
A workaround for Danger JS STDIN timeout issues. If your process cannot catch the DSL, have it print 'danger://send-dsl' to trigger a re-send.
```text
danger://send-dsl
```
--------------------------------
### Run Danger JS on a PR
Source: https://github.com/danger/danger-js/blob/main/README.md
Build the project and run your local development copy of Danger JS against a specific GitHub pull request using its URL.
```sh
yarn build; node --inspect distribution/commands/danger-pr.js https://github.com/danger/danger-js/pull/817
```
--------------------------------
### Release a New Version of Danger JS
Source: https://github.com/danger/danger-js/blob/main/README.md
Follow the release process by checking out the main branch, ensuring a clean working tree, and publishing a new version using npm. This triggers a CI run to update homebrew.
```sh
npm run release -- patch --ci --npm.otp=
```
--------------------------------
### Local Testing Workflow for Danger Plugins
Source: https://github.com/danger/danger-js/blob/main/docs/usage/extending-danger.html.md
A sequence of commands for locally testing a Danger plugin against a real pull request. This involves linking the plugin and using `danger pr`.
```sh
yarn link
yarn add [plugin] -d
yarn link [plugin]
yarn tsc --watch
yarn danger pr -v https://github.com/artsy/emission/pull/597
```
--------------------------------
### Run Danger as a Dev-Dependency in CI
Source: https://github.com/danger/danger-js/blob/main/docs/usage/github_enterprise.html.md
Integrate Danger as a build step after tests when Danger is a dev-dependency. Ensure `DANGER_GHE_ACTIONS_BOT_USER_ID` is set in your environment.
```yml
name: Node CI
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Use Node.js 10.x
uses: actions/setup-node@v1
with:
node-version: 10.x
- name: install yarn
run: npm install -g yarn
- name: yarn install, build, and test
run: |
yarn install --frozen-lockfile
yarn build
yarn test
- name: Danger
run: yarn danger ci
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DANGER_GHE_ACTIONS_BOT_USER_ID: *user_id*
```
--------------------------------
### Generate Requested Reviewers Fixture
Source: https://github.com/danger/danger-js/blob/main/source/platforms/_tests/fixtures/readme.md
Use this CURL command to fetch and save the requested reviewers for a pull request as a JSON fixture.
```sh
curl \
-H "Authorization: token " \
-H "Accept: application/vnd.github.v3+json" \
--request GET https://api.github.com/repos/artsy/emission/pulls/327/requested_reviewers \
> source/platforms/_tests/fixtures/requested_reviewers.json
```
--------------------------------
### Bitbucket Cloud DSL Overview
Source: https://github.com/danger/danger-js/blob/main/docs/usage/bitbucket_cloud.html.md
This outlines the available properties within the `danger.bitbucket_cloud` object for accessing pull request metadata, PR details, commits, comments, and activities.
```typescript
danger.bitbucket_cloud.
/** The pull request and repository metadata */
metadata: RepoMetaData
/** The PR metadata */
pr: BitBucketCloudPRDSL
/** The commits associated with the pull request */
commits: BitBucketCloudCommit[]
/** The comments on the pull request */
comments: BitBucketCloudPRComment[]
/** The activities such as OPENING, COMMENTING, CLOSING, MERGING or UPDATING a pull request */
activities: BitBucketCloudPRActivity[]
```
--------------------------------
### Check Linter Output for Failures
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-app.html.md
Reads a linter output file and posts a markdown message to the PR if 'Failed' is found.
```javascript
import { danger, markdown } from "danger"
import contains from "lodash-contains"
import fs from "fs"
const testFile = "tests-output.log"
const linterOutput = fs.readFileSync(testFile).toString()
if (contains(linterOutput, "Failed")) {
markdown(`These changes failed to pass the linter:
${linterOutput}
`)
}
```
--------------------------------
### Simple Ruby Danger Process Runner
Source: https://github.com/danger/danger-js/blob/main/docs/usage/danger-process.html.md
A minimal Danger runner implemented in Ruby. It reads the Danger DSL from STDIN, parses it, and checks if the PR body includes 'Hello world'. Results are output as JSON to STDOUT. This runner can be executed with `danger pr --process 'dangerfile.rb` after making it executable.
```ruby
#!/usr/bin/env ruby
require 'json'
dsl_json = STDIN.tty? ? 'Cannot read from STDIN' : $stdin.read
danger = JSON.parse(dsl_json).danger
results = { warnings: [], messages:[], fails: [], markdowns: [] }
if danger.github.pr.body.include? "Hello world"
results.messages << { message: "Hey there" }
end
STDOUT.write(results.to_json)
```
--------------------------------
### Fail on blacklisted dependency addition
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/dependencies.html.md
This snippet checks for the addition of specific blacklisted dependencies in package.json. It uses `JSONDiffForFile` to detect changes and `fail` to stop the build if a blacklisted package is found.
```javascript
const blacklist = "spaced-between"
schedule(async () => {
const packageDiff = await danger.git.JSONDiffForFile("package.json")
if (packageDiff.dependencies) {
const newDependencies = packageDiff.dependencies.added
if (newDependencies.includes(blacklist)) {
fail(`Do not add ${blacklist} to our dependencies, see CVE #23")
}
}
})
```
--------------------------------
### Enforce Jira Issues and User Approvals with Danger JS
Source: https://github.com/danger/danger-js/blob/main/docs/usage/bitbucket_server.html.md
Demonstrates how to enforce that a PR has assigned Jira issues and checks for specific user approvals on package.json changes.
```typescript
import { danger, warn } from "danger"
const bbs = danger.bitbucket_server
// Ensure a PR has assigned Jira issues
if (bbs.issues.length === 0) {
warn("This PR does not have any assigned Jira issues.")
}
// Make a warning if there are changes to a package.json but that a
// user called murphdog hasn't yet weighed in that the changes are fine.
const hasPackageChanges = danger.git.modified_files.includes("package.json")
const hasMurphDogApproval = bbs.comments.find(
c => c.user.slug == "murphdog" && !!c.comment && c.comment.text.includes(":+1:")
)
if (hasPackageChanges && !hasMurphDogApproval) {
warn("This PR has `package.json` changes, but @murphdog hasn't approved them yet.")
}
```
--------------------------------
### Handle Async Operations with schedule in Peril
Source: https://github.com/danger/danger-js/blob/main/docs/guides/peril.html.md
Use the `schedule` function within your Dangerfile to manage asynchronous operations. It queues promises or functions with callbacks, ensuring Danger waits for completion before proceeding. This is crucial for handling async code in Peril's inline execution environment.
```javascript
import { schedule, danger } from "danger"
/// [... a bunch of functions]
schedule(async () => {
const packageDiff = await danger.git.JSONDiffForFile("package.json")
checkForRelease(packageDiff)
checkForNewDependencies(packageDiff)
checkForLockfileDiff(packageDiff)
checkForTypesInDeps(packageDiff)
})
```
--------------------------------
### Warn on package.json changes without lockfile changes
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/dependencies.html.md
Use this to ensure that any modifications to package.json are accompanied by corresponding changes in the lockfile (e.g., yarn.lock). This helps maintain a consistent dependency state.
```javascript
import { danger, warn } from "danger"
const packageJson = danger.git.fileMatch("package.json")
const packageLock = danger.git.fileMatch("yarn.lock")
if (packageJson.modified && !packageLock.modified) {
warn("There are package.json changes with no corresponding lockfile changes")
}
```
--------------------------------
### Conditionally Run Danger CI
Source: https://github.com/danger/danger-js/blob/main/docs/guides/faq.html.md
Use this command to ensure Danger only runs when the necessary environment variables are set, preventing external contributors from accessing private tokens.
```sh
[ ! -z $DANGER_GITHUB_API_TOKEN ] && yarn danger ci || echo "Skipping Danger for External Contributor"
```
--------------------------------
### Release a New Version of Danger JS
Source: https://github.com/danger/danger-js/blob/main/CONTRIBUTING.md
Steps to update the version, commit changes, tag the release, and push to the main branch for deployment to NPM.
```sh
git pull
# Update package.json with the new version (e.g., 0.21.0)
# Modify changelog.md with a new heading (e.g., ### 0.21.0)
# Commit both changes
git commit -m "Version bump"
# Tag this commit
git tag 0.21.0
# Push the commit and tag
git push origin main --follow-tags
```
--------------------------------
### Conditional Assignee Check (WIP)
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-app.html.md
Allows PRs with 'WIP' in the title to skip the assignee check, issuing a warning instead of a failure.
```javascript
import { danger, fail, warn } from "danger"
if (!danger.github.pr.assignee) {
const method = danger.github.pr.title.includes("WIP") ? warn : fail
method("This pull request needs an assignee, and optionally include any reviewers.")
}
```
--------------------------------
### Mock Danger Module for Testing
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/transpilation.html.md
Mock the 'danger' module using Jest to simulate the Danger environment for testing Dangerfiles. This allows manipulation of objects like danger.github.pr.
```javascript
jest.mock("danger", () => jest.fn())
import * as danger from "danger"
const dm = danger as any
import { rfc5 } from "../org/all-prs"
beforeEach(() => {
dm.fail = jest.fn()
})
it("fails when there's no PR body", () => {
dm.danger = { github: { pr: { body: "" } } }
return rfc5().then(() => {
expect(dm.fail).toHaveBeenCalledWith("Please add a description to your PR.")
})
})
it("does nothing when there's a PR body", () => {
dm.danger = { github: { pr: { body: "Hello world" } } }
return rfc5().then(() => {
expect(dm.fail).not.toHaveBeenCalled()
})
})
```
--------------------------------
### Main Dangerfile Logic for Reviewer Roulette
Source: https://github.com/danger/danger-js/blob/main/source/platforms/gitlab/_tests/fixtures/fileContentsBefore.txt
This block orchestrates the reviewer roulette process. It fetches changes, determines categories, and conditionally applies the roulette if the MR is not a 'single codebase' or 'CSS cleanup' type.
```ruby
changes = helper.changes_by_category
# Ignore any files that are known but uncategoried. Prompt for any unknown files
changes.delete(:none)
categories = changes.keys - [:unknown]
# Single codebase MRs are reviewed using a slightly different process, so we
# disable the review roulette for such MRs.
# CSS Clean up MRs are reviewed using a slightly different process, so we
# disable the review roulette for such MRs.
if changes.any? && !gitlab.mr_labels.include?('single codebase') && !gitlab.mr_labels.include?('CSS cleanup')
team =
begin
helper.project_team
rescue => err
warn("Reviewer roulette failed to load team data: #{err.message}")
[]
end
# Exclude the MR author from the team for selection purposes
team.delete_if { |teammate| teammate.username == gitlab.mr_author }
project = helper.project_name
unknown = changes.fetch(:unknown, [])
rows = categories.map { |category| spin(team, project, category) }
markdown(MESSAGE)
markdown(CATEGORY_TABLE_HEADER + rows.join("\n")) unless rows.empty?
markdown(UNKNOWN_FILES_MESSAGE + build_list(unknown)) unless unknown.empty?
end
```
--------------------------------
### Use Danger JS as a GitHub Action
Source: https://github.com/danger/danger-js/blob/main/docs/usage/github_enterprise.html.md
Utilize Danger JS as a standalone action for CI workflows. This method is suitable if you are not running in a JavaScript ecosystem or prefer not to include Danger as a dependency. Set `DANGER_GHE_ACTIONS_BOT_USER_ID` in your environment.
```yml
name: "Danger JS"
on: [pull_request]
jobs:
build:
name: Danger JS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Danger
uses: danger/danger-js@9.1.6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DANGER_GHE_ACTIONS_BOT_USER_ID: *user_id*
```
--------------------------------
### Configure TypeScript Exclusion and Inclusion
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/transpilation.html.md
Add your Dangerfile to the 'exclude' section and 'include' section in tsconfig.json to prevent compilation errors and enable inline error checking.
```json
{
"compilerOptions": {},
"include": ["src/**/*.ts", "src/**/*.tsx", "dangerfile.ts"],
"exclude": ["dangerfile.ts", "node_modules"]
}
```
--------------------------------
### Warn on Missing CHANGELOG Entry
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-library.html.md
Use this rule to warn if a pull request modifies files but does not include a CHANGELOG.md update. This helps ensure documentation is kept up-to-date.
```javascript
import { danger, fail, warn } from "danger"
const changelogChanges = danger.git.fileMatch("CHANGELOG.md")
if (!changelogChanges.modified) {
warn("This pull request may need a CHANGELOG entry.")
}
```
--------------------------------
### Minimum PR Description Length
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-app.html.md
Enforces a minimum length for the pull request body to encourage documentation.
```javascript
if (danger.github.pr.body.length < 10) {
fail("This pull request needs a description.")
}
```
--------------------------------
### Access GitLab MR Metadata in Dangerfile
Source: https://github.com/danger/danger-js/blob/main/docs/usage/gitlab.html.md
This shows the available properties within the `danger.gitlab` object for accessing merge request metadata, repository details, and commits.
```typescript
danger.gitlab.
/** The pull request and repository metadata */
metadata: RepoMetaData
/** The Merge Request metadata */
mr: GitLabMR
/** The commits associated with the merge request */
commits: GitLabMRCommit[]
```
--------------------------------
### Check for WIP in PR Title
Source: https://github.com/danger/danger-js/blob/main/docs/usage/bitbucket_cloud.html.md
Use this snippet to warn if a pull request title indicates it's a Work In Progress. Requires the `danger.bitbucket_cloud.pr.title` property.
```typescript
import { danger, warn } from "danger"
if (danger.bitbucket_cloud.pr.title.includes("WIP")) {
warn("PR is considered WIP")
}
```
--------------------------------
### Advanced Ruby Danger Process Runner
Source: https://github.com/danger/danger-js/blob/main/docs/usage/danger-process.html.md
A more complex Ruby runner that simulates the Dangerfile evaluation environment. It defines methods for `warn`, `fail`, `markdowns`, and `messages` within a `Dangerfile` class. It reads and evaluates a local Dangerfile, writing results to a temporary file and outputting its path to STDOUT.
```ruby
#!/usr/bin/env ruby
require 'json'
dsl_json = STDIN.tty? ? 'Cannot read from STDIN' : $stdin.read
danger = JSON.parse(dsl_json).danger
results = { warnings: [], messages:[], fails: [], markdowns: [] }
filename = "Dangerfile"
class Dangerfile
# All these functions are effectively globals inside
# the Dangerfile during evaluation
def warn(msg)
results.warnings << { message: msg }
end
def fail(msg)
results.fails << { message: msg }
end
def markdowns(msg)
results.markdowns << { message: msg }
end
def messages(msg)
results.messages << { message: msg }
end
def run
instance_eval do
begin
# Eval the cwd's Dangerfile in the context
# of this file, making it a custom runtime
eval(File.read(filename), nil, filename)
# Writes the results to a tmpdir file, then
# pass it back to danger-js by putting the
# url of the file back via stdout
results_path = Dir.tmpdir + "danger-results.json"
File.write(results_path, results.to_json)
puts "danger-results:/" + results_path
rescue Exception => e
# Generic error handling
message = "Invalid `#{path.basename}` file: #{e.message}"
raise Error.new(message, path, e.backtrace, contents)
end
end
end
end
```
--------------------------------
### Spin Function for Reviewer Selection
Source: https://github.com/danger/danger-js/blob/main/source/platforms/gitlab/_tests/fixtures/fileContentsAfter.txt
Selects a reviewer and maintainer for a given category based on team roles and project. It uses a seeded random number generator for consistent selection based on the branch name and prioritizes traintainers for reviewer roles.
```ruby
def spin(team, project, category, branch_name)
rng = Random.new(Digest::MD5.hexdigest(branch_name).to_i(16))
reviewers = team.select { |member| member.reviewer?(project, category) }
traintainers = team.select { |member| member.traintainer?(project, category) }
maintainers = team.select { |member| member.maintainer?(project, category) }
# TODO: filter out people who are currently not in the office
# https://gitlab.com/gitlab-org/gitlab-ce/issues/57652
#
# TODO: take CODEOWNERS into account?
# https://gitlab.org/gitlab-ce/issues/57653
# Make traintainers have triple the chance to be picked as a reviewer
reviewer = (reviewers + traintainers + traintainers).sample(random: rng)
maintainer = maintainers.sample(random: rng)
"| #{helper.label_for_category(category)} | #{reviewer&.markdown_name} | #{maintainer&.markdown_name} |"
end
```
--------------------------------
### Basic PR Title Check with Danger JS
Source: https://github.com/danger/danger-js/blob/main/docs/usage/bitbucket_server.html.md
Checks if the pull request title includes 'WIP' and issues a warning if it does. Requires Danger JS to be set up.
```typescript
import { danger, warn } from "danger"
if (danger.bitbucket_server.pr.title.includes("WIP")) {
warn("PR is considered WIP")
}
```
--------------------------------
### Main Danger JS Logic for GitLab
Source: https://github.com/danger/danger-js/blob/main/source/platforms/gitlab/_tests/fixtures/fileContentsAfter.txt
Orchestrates the reviewer roulette process for GitLab merge requests. It fetches changes, determines categories, selects reviewers and maintainers, and generates markdown output, excluding certain MRs like 'single codebase' or 'CSS cleanup'.
```ruby
changes = helper.changes_by_category
# Ignore any files that are known but uncategoried. Prompt for any unknown files
changes.delete(:none)
categories = changes.keys - [:unknown]
# Single codebase MRs are reviewed using a slightly different process, so we
# disable the review roulette for such MRs.
# CSS Clean up MRs are reviewed using a slightly different process, so we
# disable the review roulette for such MRs.
if changes.any? && !gitlab.mr_labels.include?('single codebase') && !gitlab.mr_labels.include?('CSS cleanup')
# Strip leading and trailing CE/EE markers
canonical_branch_name = gitlab
.mr_json['source_branch']
.gsub(/^[ce]e-/, '')
.gsub(/-[ce]e$/, '')
team =
begin
helper.project_team
rescue => err
warn("Reviewer roulette failed to load team data: #{err.message}")
[]
end
# Exclude the MR author from the team for selection purposes
team.delete_if { |teammate| teammate.username == gitlab.mr_author }
project = helper.project_name
unknown = changes.fetch(:unknown, [])
rows = categories.map { |category| spin(team, project, category, canonical_branch_name) }
markdown(MESSAGE)
markdown(CATEGORY_TABLE_HEADER + rows.join("\n")) unless rows.empty?
markdown(UNKNOWN_FILES_MESSAGE + build_list(unknown)) unless unknown.empty?
end
```
--------------------------------
### Fail on blacklisted dependency in lockfile
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/dependencies.html.md
This rule parses the yarn.lock file to detect if a blacklisted dependency has been introduced, even transitively. It uses synchronous file reading for simplicity in a script environment.
```javascript
import fs from "fs"
const blacklist = "spaced-between"
const lockfile = fs.readFileSync("yarn.lock").toString()
if (lockfile.includes(blacklist)) {
const message = `${blacklist} was added to our dependencies, see CVE #23`
const hint = `To find out what introduced it, use 'yarn why ${blacklist}'.`
fail(`${message}
${hint}`)
}
```
--------------------------------
### Spin Function for Reviewer Selection
Source: https://github.com/danger/danger-js/blob/main/source/platforms/gitlab/_tests/fixtures/fileContentsBefore.txt
This function selects a reviewer and maintainer for a given category based on team roles. It prioritizes traintainers for reviewer selection and handles cases where no maintainer is found.
```ruby
def spin(team, project, category)
reviewers = team.select { |member| member.reviewer?(project, category) }
traintainers = team.select { |member| member.traintainer?(project, category) }
maintainers = team.select { |member| member.maintainer?(project, category) }
# TODO: filter out people who are currently not in the office
# TODO: take CODEOWNERS into account?
# Make traintainers have triple the chance to be picked as a reviewer
reviewer = (reviewers + traintainers + traintainers).sample
maintainer = maintainers.sample
"| #{helper.label_for_category(category)} | #{reviewer&.markdown_name} | #{maintainer&.markdown_name} |"
end
```
--------------------------------
### Check Merge Request Title in Dangerfile
Source: https://github.com/danger/danger-js/blob/main/docs/usage/gitlab.html.md
Use this snippet to check if a merge request title contains specific keywords like 'WIP'. Ensure you have imported `danger` and `warn` from 'danger'.
```typescript
import { danger, warn } from "danger"
if (danger.gitlab.mr.title.includes("WIP")) {
warn("PR is considered WIP")
}
```
--------------------------------
### Require Assignee for PRs
Source: https://github.com/danger/danger-js/blob/main/docs/tutorials/node-app.html.md
Ensures a pull request has an assignee. Fails the build if no assignee is present.
```javascript
import { danger, fail, warn } from "danger"
if (!danger.github.pr.assignee) {
fail("This pull request needs an assignee, and optionally include any reviewers.")
}
```
--------------------------------
### Define Reviewer Roulette Messages
Source: https://github.com/danger/danger-js/blob/main/source/platforms/gitlab/_tests/fixtures/fileContentsBefore.txt
These constants define the markdown messages used for the reviewer roulette feature, including introductory text and table headers.
```ruby
MESSAGE = <