PkgTemplates.jl/src/plugins/ci.jl

337 lines
11 KiB
Julia
Raw Normal View History

2019-09-18 14:22:04 +00:00
"""
format_version(v::Union{VersionNumber, AbstractString}) -> String
Strip everything but the major and minor release from a `VersionNumber`.
Strings are left in their original form.
"""
format_version(v::VersionNumber) = "$(v.major).$(v.minor)"
2019-08-29 16:04:11 +00:00
format_version(v::AbstractString) = string(v)
const ALLOWED_FAILURES = ["1.3", "nightly"] # TODO: Update this list with new RCs.
const DEFAULT_CI_VERSIONS = map(format_version, [default_version(), VERSION, "nightly"])
2019-10-06 07:43:17 +00:00
const DEFAULT_CI_VERSIONS_NO_NIGHTLY = map(format_version, [default_version(), VERSION])
const EXTRA_VERSIONS_DOC = "- `extra_versions::Vector`: Extra Julia versions to test, as strings or `VersionNumber`s."
"""
collect_versions(t::Template, versions::Vector) -> Vector{String}
2019-09-18 14:22:04 +00:00
Combine `t`'s Julia version with `versions`, and format them as `major.minor`.
This is useful for creating lists of versions to be included in CI configurations.
"""
2019-08-29 16:04:11 +00:00
function collect_versions(t::Template, versions::Vector)
2019-09-25 13:48:39 +00:00
vs = map(format_version, [t.julia, versions...])
2019-08-31 14:09:22 +00:00
return sort(unique(vs))
end
"""
TravisCI(;
file="$(contractuser(default_file("travis.yml")))",
linux=true,
osx=true,
windows=true,
x86=false,
2019-11-01 02:27:12 +00:00
arm=false,
coverage=true,
extra_versions=$DEFAULT_CI_VERSIONS,
2019-09-18 14:22:04 +00:00
)
Integrates your packages with [Travis CI](https://travis-ci.com).
## Keyword Arguments
- `file::AbstractString`: Template file for `.travis.yml`.
- `linux::Bool`: Whether or not to run builds on Linux.
- `osx::Bool`: Whether or not to run builds on OSX (MacOS).
- `windows::Bool`: Whether or not to run builds on Windows.
2019-10-06 09:55:32 +00:00
- `x86::Bool`: Whether or not to run builds on 32-bit systems,
in addition to the default 64-bit builds.
2019-11-01 02:27:12 +00:00
- `arm::Bool`: Whether or not to run builds on the ARM architecture, in addition to AMD64.
2019-10-06 09:55:32 +00:00
- `coverage::Bool`: Whether or not to publish code coverage.
Another code coverage plugin such as [`Codecov`](@ref) must also be included.
$EXTRA_VERSIONS_DOC
"""
2019-10-06 07:43:17 +00:00
@with_kw_noshow struct TravisCI <: BasicPlugin
file::String = default_file("travis.yml")
linux::Bool = true
osx::Bool = true
windows::Bool = true
x86::Bool = false
2019-11-01 02:27:12 +00:00
arm::Bool = false
2019-10-06 07:43:17 +00:00
coverage::Bool = true
extra_versions::Vector = DEFAULT_CI_VERSIONS
end
source(p::TravisCI) = p.file
destination(::TravisCI) = ".travis.yml"
badges(::TravisCI) = Badge(
"Build Status",
2019-09-18 15:27:16 +00:00
"https://travis-ci.com/{{{USER}}}/{{{PKG}}}.jl.svg?branch=master",
"https://travis-ci.com/{{{USER}}}/{{{PKG}}}.jl",
)
function view(p::TravisCI, t::Template, pkg::AbstractString)
2019-08-27 05:43:10 +00:00
os = String[]
p.linux && push!(os, "linux")
p.osx && push!(os, "osx")
p.windows && push!(os, "windows")
2019-08-29 16:04:11 +00:00
versions = collect_versions(t, p.extra_versions)
allow_failures = filter(in(versions), ALLOWED_FAILURES)
2019-08-27 05:43:10 +00:00
2019-11-01 02:27:12 +00:00
jobs = Dict{String, String}[]
2019-08-27 05:43:10 +00:00
if p.x86
foreach(versions) do v
2019-11-01 02:27:12 +00:00
p.linux && push!(jobs, Dict("JULIA" => v, "OS" => "linux", "ARCH" => "x86"))
p.windows && push!(jobs, Dict("JULIA" => v, "OS" => "windows", "ARCH" => "x86"))
end
end
if p.arm
foreach(versions) do v
p.linux && push!(jobs, Dict("JULIA" => v, "OS" => "linux", "ARCH" => "arm64"))
end
end
2019-08-27 05:43:10 +00:00
return Dict(
2019-08-27 05:43:10 +00:00
"ALLOW_FAILURES" => allow_failures,
"HAS_ALLOW_FAILURES" => !isempty(allow_failures),
"HAS_CODECOV" => hasplugin(t, Codecov),
2019-08-29 16:04:11 +00:00
"HAS_COVERAGE" => p.coverage && hasplugin(t, is_coverage),
"HAS_COVERALLS" => hasplugin(t, Coveralls),
"HAS_DOCUMENTER" => hasplugin(t, Documenter{TravisCI}),
2019-11-01 02:27:12 +00:00
"HAS_JOBS" => !isempty(jobs) || hasplugin(t, Documenter{TravisCI}),
2019-08-27 05:43:10 +00:00
"OS" => os,
"PKG" => pkg,
2019-08-29 16:04:11 +00:00
"USER" => t.user,
2019-09-25 13:48:39 +00:00
"VERSION" => format_version(t.julia),
2019-08-29 16:04:11 +00:00
"VERSIONS" => versions,
2019-11-01 02:27:12 +00:00
"JOBS" => jobs,
)
end
"""
AppVeyor(;
file="$(contractuser(default_file("appveyor.yml")))",
x86=false,
coverage=true,
extra_versions=$DEFAULT_CI_VERSIONS,
2019-09-18 14:22:04 +00:00
)
2019-10-06 09:55:32 +00:00
Integrates your packages with [AppVeyor](https://appveyor.com)
via [AppVeyor.jl](https://github.com/JuliaCI/Appveyor.jl).
## Keyword Arguments
- `file::AbstractString`: Template file for `.appveyor.yml`.
2019-10-06 09:55:32 +00:00
- `x86::Bool`: Whether or not to run builds on 32-bit systems,
in addition to the default 64-bit builds.
- `coverage::Bool`: Whether or not to publish code coverage.
[`Codecov`](@ref) must also be included.
$EXTRA_VERSIONS_DOC
"""
2019-10-06 07:43:17 +00:00
@with_kw_noshow struct AppVeyor <: BasicPlugin
file::String = default_file("appveyor.yml")
x86::Bool = false
coverage::Bool = true
extra_versions::Vector = DEFAULT_CI_VERSIONS
end
source(p::AppVeyor) = p.file
destination(::AppVeyor) = ".appveyor.yml"
badges(::AppVeyor) = Badge(
"Build Status",
2019-09-18 15:27:16 +00:00
"https://ci.appveyor.com/api/projects/status/github/{{{USER}}}/{{{PKG}}}.jl?svg=true",
"https://ci.appveyor.com/project/{{{USER}}}/{{{PKG}}}-jl",
)
2019-08-29 16:04:11 +00:00
function view(p::AppVeyor, t::Template, pkg::AbstractString)
platforms = ["x64"]
2019-08-29 16:04:11 +00:00
p.x86 && push!(platforms, "x86")
versions = collect_versions(t, p.extra_versions)
allow_failures = filter(in(versions), ALLOWED_FAILURES)
return Dict(
2019-08-29 16:04:11 +00:00
"ALLOW_FAILURES" => allow_failures,
"HAS_ALLOW_FAILURES" => !isempty(allow_failures),
"HAS_CODECOV" => p.coverage && hasplugin(t, Codecov),
"PKG" => pkg,
2019-08-29 16:04:11 +00:00
"PLATFORMS" => platforms,
"USER" => t.user,
"VERSIONS" => versions,
)
end
"""
CirrusCI(;
file="$(contractuser(default_file("cirrus.yml")))",
image="freebsd-12-0-release-amd64",
coverage=true,
extra_versions=$DEFAULT_CI_VERSIONS,
2019-09-18 14:22:04 +00:00
)
2019-10-06 09:55:32 +00:00
Integrates your packages with [Cirrus CI](https://cirrus-ci.org)
via [CirrusCI.jl](https://github.com/ararslan/CirrusCI.jl).
## Keyword Arguments
- `file::AbstractString`: Template file for `.cirrus.yml`.
- `image::AbstractString`: The FreeBSD image to be used.
2019-10-06 09:55:32 +00:00
- `coverage::Bool`: Whether or not to publish code coverage.
[`Codecov`](@ref) must also be included.
$EXTRA_VERSIONS_DOC
!!! note
2019-10-06 09:55:32 +00:00
Code coverage submission from Cirrus CI is not yet supported by
[Coverage.jl](https://github.com/JuliaCI/Coverage.jl).
"""
2019-10-06 07:43:17 +00:00
@with_kw_noshow struct CirrusCI <: BasicPlugin
file::String = default_file("cirrus.yml")
image::String = "freebsd-12-0-release-amd64"
coverage::Bool = true
extra_versions::Vector = DEFAULT_CI_VERSIONS
end
source(p::CirrusCI) = p.file
destination(::CirrusCI) = ".cirrus.yml"
badges(::CirrusCI) = Badge(
"Build Status",
2019-09-18 15:27:16 +00:00
"https://api.cirrus-ci.com/github/{{{USER}}}/{{{PKG}}}.jl.svg",
"https://cirrus-ci.com/github/{{{USER}}}/{{{PKG}}}.jl",
)
2019-08-31 11:45:41 +00:00
function view(p::CirrusCI, t::Template, pkg::AbstractString)
return Dict(
"HAS_CODECOV" => hasplugin(t, Codecov),
"HAS_COVERALLS" => hasplugin(t, Coveralls),
2019-08-29 16:04:11 +00:00
"HAS_COVERAGE" => p.coverage && hasplugin(t, is_coverage),
"IMAGE" => p.image,
"PKG" => pkg,
2019-08-29 16:04:11 +00:00
"USER" => t.user,
"VERSIONS" => collect_versions(t, p.extra_versions),
)
end
"""
GitLabCI(;
file="$(contractuser(default_file("gitlab-ci.yml")))",
coverage=true,
2019-10-06 07:43:17 +00:00
extra_versions=$DEFAULT_CI_VERSIONS_NO_NIGHTLY,
2019-09-18 14:22:04 +00:00
)
2019-10-06 09:55:32 +00:00
Integrates your packages with [GitLab CI](https://docs.gitlab.com/ce/ci).
## Keyword Arguments
- `file::AbstractString`: Template file for `.gitlab-ci.yml`.
- `coverage::Bool`: Whether or not to compute code coverage.
$EXTRA_VERSIONS_DOC
## GitLab Pages
Documentation can be generated by including a `Documenter{GitLabCI}` plugin.
See [`Documenter`](@ref) for more information.
!!! note
Nightly Julia is not supported.
"""
2019-10-06 07:43:17 +00:00
@with_kw_noshow struct GitLabCI <: BasicPlugin
file::String = default_file("gitlab-ci.yml")
coverage::Bool = true
2019-08-31 14:09:22 +00:00
# Nightly has no Docker image.
2019-10-06 07:43:17 +00:00
extra_versions::Vector = DEFAULT_CI_VERSIONS_NO_NIGHTLY
end
gitignore(p::GitLabCI) = p.coverage ? COVERAGE_GITIGNORE : String[]
2019-08-31 11:45:41 +00:00
source(p::GitLabCI) = p.file
destination(::GitLabCI) = ".gitlab-ci.yml"
function badges(p::GitLabCI)
ci = Badge(
"Build Status",
2019-09-18 15:27:16 +00:00
"https://gitlab.com/{{{USER}}}/{{{PKG}}}.jl/badges/master/build.svg",
"https://gitlab.com/{{{USER}}}/{{{PKG}}}.jl/pipelines",
)
cov = Badge(
"Coverage",
2019-09-18 15:27:16 +00:00
"https://gitlab.com/{{{USER}}}/{{{PKG}}}.jl/badges/master/coverage.svg",
"https://gitlab.com/{{{USER}}}/{{{PKG}}}.jl/commits/master",
)
return p.coverage ? [ci, cov] : [ci]
end
2019-08-31 11:45:41 +00:00
function view(p::GitLabCI, t::Template, pkg::AbstractString)
return Dict(
"HAS_COVERAGE" => p.coverage,
"HAS_DOCUMENTER" => hasplugin(t, Documenter{GitLabCI}),
"PKG" => pkg,
2019-08-29 16:04:11 +00:00
"USER" => t.user,
2019-09-25 13:48:39 +00:00
"VERSION" => format_version(t.julia),
2019-08-29 16:04:11 +00:00
"VERSIONS" => collect_versions(t, p.extra_versions),
)
end
2019-08-29 16:04:11 +00:00
"""
DroneCI(;
file="$(contractuser(default_file("drone.star")))",
amd64=true,
arm=false,
arm64=false,
extra_versions=$DEFAULT_CI_VERSIONS_NO_NIGHTLY,
)
Integrates your packages with [Drone CI](https://drone.io).
## Keyword Arguments
- `file::AbstractString`: Template file for `.drone.star`.
- `destination::AbstractString`: File destination, relative to the repository root.
For example, you might want to generate a `.drone.yml` instead of the default Starlark file.
- `amd64::Bool`: Whether or not to run builds on AMD64.
- `arm::Bool`: Whether or not to run builds on ARM (32-bit).
2019-10-06 09:55:32 +00:00
- `arm64::Bool`: Whether or not to run builds on ARM64.
$EXTRA_VERSIONS_DOC
!!! note
Nightly Julia is not supported.
"""
@with_kw_noshow struct DroneCI <: BasicPlugin
file::String = default_file("drone.star")
destination::String = ".drone.star"
amd64::Bool = true
arm::Bool = false
arm64::Bool = false
extra_versions::Vector = DEFAULT_CI_VERSIONS_NO_NIGHTLY
end
source(p::DroneCI) = p.file
destination(p::DroneCI) = p.destination
badges(::DroneCI) = Badge(
"Build Status",
"https://cloud.drone.io/api/badges/{{{USER}}}/{{{PKG}}}.jl/status.svg",
"https://cloud.drone.io/{{{USER}}}/{{{PKG}}}.jl",
)
function view(p::DroneCI, t::Template, pkg::AbstractString)
arches = String[]
p.amd64 && push!(arches, "amd64")
p.arm && push!(arches, "arm")
p.arm64 && push!(arches, "arm64")
return Dict(
"ARCHES" => join(map(repr, arches), ", "),
"PKG" => pkg,
"USER" => t.user,
"VERSIONS" => join(map(repr, collect_versions(t, p.extra_versions)), ", "),
)
end
"""
2019-09-20 02:31:56 +00:00
is_ci(::Plugin) -> Bool
2019-09-20 02:31:56 +00:00
Determine whether or not a plugin is a CI plugin.
If you are adding a CI plugin, you should implement this function and return `true`.
"""
2019-09-20 02:31:56 +00:00
is_ci(::Plugin) = false
is_ci(::Union{AppVeyor, TravisCI, CirrusCI, GitLabCI, DroneCI}) = true
needs_username(::Union{AppVeyor, TravisCI, CirrusCI, GitLabCI, DroneCI}) = true