The Dangerfile
#Writing your Dangerfile
All of Danger is built in Swift, so it feels Swift-y aims to have 100% in-line docs. This means a lot of your
exploration can be done inside Xcode. This document aims to give you some high level knowledge on how to work on your
Dangerfile.swift
.
#Editing your Dangerfile
Because there’s a bit of runtime trickery when evaluating your Dangerfile, and because Xcode works on projects, not files: there is a command for editing your Dangerfile in a sandbox’d environment (including all plugins too).
[swift run] danger-swift edit
#Working on your Dangerfile
There are two ways to locally work on your Dangerfile. These both rely on using an external API locally, so you may hit their API rate-limits or need to have authenticated request for private repos. In which case you can use an access token to do authenticated requests by exposing a token to Danger.
export DANGER_GITHUB_API_TOKEN='xxxx'
# or for BitBucket by username and password
export DANGER_BITBUCKETSERVER_HOST='xxxx' DANGER_BITBUCKETSERVER_USERNAME='yyyy' DANGER_BITBUCKETSERVER_PASSWORD='zzzz'
# or for BitBucket by username and personal access token
export DANGER_BITBUCKETSERVER_HOST='xxxx' DANGER_BITBUCKETSERVER_USERNAME='yyyy' DANGER_BITBUCKETSERVER_TOKEN='zzzz'
Then the danger CLI will use authenticated API calls, which don’t get hit by API limits.
#Using danger pr
The command danger-swift pr
expects an argument of a PR url, e.g:
[swift run] danger-swift pr https://github.com/danger/swift/pull/95
This will use your local Dangerfile.swift
against the metadata of the linked PR. Danger will then output the results
into your terminal, instead of inside the PR itself.
This will not post comments in that PR.
#Using danger
and Faking being on a CI
If you create an appropriately scoped temporary api token for your GitHub account, this can be a good way to see if danger is suitable for you before integrating it into your CI system.
You can manually trigger danger against a pull request on the command line by setting the following environmental variables:
export DANGER_FAKE_CI="YEP"
export DANGER_TEST_REPO='username/reponame'
Then you can run against a local branch that is attached to a pull-request, by running the following:
git checkout branch-for-pr-1234
DANGER_TEST_PR='1234' [swift run] danger-swift ci
Assuming that your local file-system matches up to that branch for your code review, this will be a good approximation of how danger will work when you integrate it into your CI system. Note: this will leave a comment on the PR.
#Plugins
#Swift Package Manager (More performant)
You can use Swift PM to install both danger-swift
and your plugins:
- Add to your
Package.swift
:
let package = Package(
...
products: [
...
// Library name must start with `DangerDeps` otherwise `Danger` won't be able to import it.
.library(name: "DangerDeps", type: .dynamic, targets: ["DangerDependencies"]), // dev
...
],
dependencies: [
...
.package(url: "https://github.com/danger/swift.git", from: "1.0.0"), // dev
// Danger Plugins
.package(url: "https://github.com/username/DangerPlugin.git", from: "0.1.0") // dev
...
],
targets: [
.target(name: "DangerDependencies", dependencies: ["Danger", "DangerPlugin"]), // dev
...
]
)
- Add the correct import to your
Dangerfile.swift
:
import DangerPlugin
DangerPlugin.doYourThing()
- Create a folder called
DangerDependencies
inSources
with an empty file inside like Fake.swift - To run
Danger
useswift run danger-swift command
-
(Recommended) If you are using Swift PM to distribute your framework, use
Rocket, or a similar tool, to comment out all the dev dependencies from your
Package.swift
. This prevents these dev dependencies from being downloaded and compiled with your framework by consumers. -
(Recommended) cache the
.build
folder on your repo
#Marathon (Easy to use)
By suffixing package: [url]
to an import, you can directly import Swift PM package as a dependency
For example, a plugin could be used by the following.
// Dangerfile.swift
import DangerPlugin // package: https://github.com/username/DangerPlugin.git
DangerPlugin.doYourThing()
(Recommended) Cache the ~/.danger-swift
folder
#Working with files
There are a few helper functions for working with files in Danger Swift.
import Danger
let danger = Danger()
// Loop through all new files, then
let swiftFilesWithCopyright = danger.git.createdFiles.filter {
$0.fileType == .swift && danger.utils.readFile($0).contains("// Created by")
}
if swiftFilesWithCopyright.count > 0 {
let files = swiftFilesWithCopyright.joined(separator: ", ")
warn("In Danger JS we don't include copyright headers, found them in: \(files)")
}
You can use $0.filetype
with any of the following enum types:
.h, .json, .m, .markdown, .mm, .pbxproj, .plist, .storyboard, .swift, .xcscheme, .yaml, .yml
Which makes it simple to easily create a few filtered arrays of files upfront depending on your needs.
#Utils
Because you’re working in a scripting-ish environment, danger.utils
provides a space for functions which are useful in
the context of making Dangerfiles. Currently these are functions that can let you skip some of the more verbose parts of
the Swift language in favour of Danger just crashing and failing the run.
#Finding more info
The CHANGELOG for Danger is kept entirely end-user focused, so if there is an aspect of the Dangerfile that you do not know, or looks confusing and there is nothing in the documentation - check the CHANGELOG. This is where we write-up why a change happened, and how it can affect Danger users.
Got improvements? Help improve this document via sending PRs.