Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for deploying from Buildkite. #1469

Merged
merged 5 commits into from
Nov 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

* ![Enhancement][badge-enhancement] Documenter now support Azure DevOps Repos URL scheme when generating edit and source links pointing to the repository. ([#1462][github-1462], [#1463][github-1463], [#1471][github-1471])

## Version `v0.25.4`

* ![Feature][badge-feature] Documenter can now deploy from Buildkite CI to GitHub Pages with `Documenter.Buildkite`. ([#1469][github-1469])

## Version `v0.25.3`

* ![Feature][badge-feature] Documenter can now deploy from GitLab CI to GitHub Pages with `Documenter.GitLab`. ([#1448][github-1448])
Expand Down Expand Up @@ -682,6 +686,7 @@
[github-1462]: https://github.com/JuliaDocs/Documenter.jl/issues/1462
[github-1463]: https://github.com/JuliaDocs/Documenter.jl/pull/1463
[github-1468]: https://github.com/JuliaDocs/Documenter.jl/pull/1468
[github-1469]: https://github.com/JuliaDocs/Documenter.jl/pull/1469
[github-1471]: https://github.com/JuliaDocs/Documenter.jl/pull/1471

[julia-38079]: https://github.com/JuliaLang/julia/issues/38079
Expand Down
7 changes: 4 additions & 3 deletions docs/src/man/hosting.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,9 +498,9 @@ It is possible to customize Documenter to use other systems then the ones descri
the sections above. This is done by passing a configuration
(a [`DeployConfig`](@ref Documenter.DeployConfig)) to `deploydocs` by the `deploy_config`
keyword argument. Documenter supports [`Travis`](@ref Documenter.Travis),
[`GitHubActions`](@ref Documenter.GitHubActions), and [`GitLab`](@ref Documenter.GitLab)
natively, but it is easy to define your own by following the simple interface
described below.
[`GitHubActions`](@ref Documenter.GitHubActions), [`GitLab`](@ref Documenter.GitLab), and
[`Buildkite`](@ref Documenter.Buildkite) natively, but it is easy to define your own by
following the simple interface described below.

```@docs
Documenter.DeployConfig
Expand All @@ -513,4 +513,5 @@ Documenter.documenter_key_previews
Documenter.Travis
Documenter.GitHubActions
Documenter.GitLab
Documenter.Buildkite
```
145 changes: 145 additions & 0 deletions src/deployconfig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,149 @@ authentication_method(::GitLab) = Documenter.SSH

documenter_key(::GitLab) = ENV["DOCUMENTER_KEY"]

#############
# Buildkite #
#############

"""
Buildkite <: DeployConfig

Buildkite implementation of `DeployConfig`.

The following environment variables influence the build when using the
`Buildkite` configuration:

- `DOCUMENTER_KEY`: must contain the Base64-encoded SSH private key for the
repository. This variable should be somehow set in the CI environment, e.g.,
provisioned by an agent environment plugin.

- `BUILDKITE_BRANCH`: the name of the commit branch.

- `BUILDKITE_PULL_REQUEST`: Pull Request ID from GitHub if the pipelines
are for external pull requests.

- `BUILDKITE_TAG`: The commit tag name. Present only when building tags.

The `BUILDKITE_*` variables are set automatically on GitLab. More information on how
Buildkite sets the `BUILDKITE_*` variables can be found in the
[Buildkite documentation](https://buildkite.com/docs/pipelines/environment-variables).
"""
struct Buildkite <: DeployConfig
commit_branch::String
pull_request::String
commit_tag::String
end

function Buildkite()
commit_branch = get(ENV, "BUILDKITE_BRANCH", "")
pull_request = get(ENV, "BUILDKITE_PULL_REQUEST", "false")
commit_tag = get(ENV, "BUILDKITE_TAG", "")
Buildkite(commit_branch, pull_request, commit_tag)
end

function deploy_folder(
cfg::Buildkite;
repo,
repo_previews = repo,
devbranch,
push_preview,
devurl,
branch = "gh-pages",
branch_previews = branch,
kwargs...,
)

marker(x) = x ? "✔" : "✘"

io = IOBuffer()
all_ok = true

println(io, "\nBuildkite config:")
println(io, " Commit branch: \"", cfg.commit_branch, "\"")
println(io, " Pull request: \"", cfg.pull_request, "\"")
println(io, " Commit tag: \"", cfg.commit_tag, "\"")

build_type = if cfg.pull_request != "false"
:preview
elseif cfg.commit_tag != ""
:release
else
:devbranch
end

println(io, "Detected build type: ", build_type)

if build_type == :release
tag_nobuild = version_tag_strip_build(cfg.commit_tag)
## If a tag exist it should be a valid VersionNumber
tag_ok = tag_nobuild !== nothing

println(
io,
"- $(marker(tag_ok)) ENV[\"BUILDKITE_TAG\"] contains a valid VersionNumber",
)
all_ok &= tag_ok

is_preview = false
subfolder = tag_nobuild
deploy_branch = branch
deploy_repo = repo
elseif build_type == :preview
pr_number = tryparse(Int, cfg.pull_request)
pr_ok = pr_number !== nothing
all_ok &= pr_ok
println(
io,
"- $(marker(pr_ok)) ENV[\"BUILDKITE_PULL_REQUEST\"]=\"$(cfg.pull_request)\" is a number",
)
btype_ok = push_preview
all_ok &= btype_ok
is_preview = true
println(
io,
"- $(marker(btype_ok)) `push_preview` keyword argument to deploydocs is `true`",
)
## deploy to previews/PR
subfolder = "previews/PR$(something(pr_number, 0))"
deploy_branch = branch_previews
deploy_repo = repo_previews
else
branch_ok = !isempty(cfg.commit_tag) || cfg.commit_branch == devbranch
all_ok &= branch_ok
println(
io,
"- $(marker(branch_ok)) ENV[\"BUILDKITE_BRANCH\"] matches devbranch=\"$(devbranch)\"",
)
is_preview = false
subfolder = devurl
deploy_branch = branch
deploy_repo = repo
end

key_ok = haskey(ENV, "DOCUMENTER_KEY")
println(io, "- $(marker(key_ok)) ENV[\"DOCUMENTER_KEY\"] exists")
all_ok &= key_ok

print(io, "Deploying to folder $(repr(subfolder)): $(marker(all_ok))")
@info String(take!(io))

if all_ok
return DeployDecision(;
all_ok = true,
branch = deploy_branch,
repo = deploy_repo,
subfolder = subfolder,
is_preview = is_preview,
)
else
return DeployDecision(; all_ok = false)
end
end

authentication_method(::Buildkite) = Documenter.SSH

documenter_key(::Buildkite) = ENV["DOCUMENTER_KEY"]

##################
# Auto-detection #
##################
Expand All @@ -647,6 +790,8 @@ function auto_detect_deploy_system()
return GitHubActions()
elseif haskey(ENV, "GITLAB_CI")
return GitLab()
elseif haskey(ENV, "BUILDKITE")
return Buildkite()
else
return nothing
end
Expand Down
84 changes: 84 additions & 0 deletions test/deployconfig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,90 @@ end end
end
end end

@testset "Buildkite CI deploy configuration" begin; with_logger(NullLogger()) do
# Regular tag build
withenv("BUILDKITE" => "true",
"BUILDKITE_BRANCH" => "master",
"BUILDKITE_PULL_REQUEST" => "false",
"BUILDKITE_TAG" => "v1.2.3",
"DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
) do
cfg = Documenter.Buildkite()
d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
devbranch="master", devurl="dev", push_preview=true)
@test d.all_ok
@test d.subfolder == "v1.2.3"
@test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
@test d.branch == "gh-pages"
@test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
@test Documenter.authentication_method(cfg) === Documenter.SSH
end
# Broken tag build
withenv("BUILDKITE" => "true",
"BUILDKITE_BRANCH" => "master",
"BUILDKITE_PULL_REQUEST" => "false",
"BUILDKITE_TAG" => "not-a-version",
"DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
) do
cfg = Documenter.Buildkite()
d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
devbranch="master", devurl="dev", push_preview=true)
@test !d.all_ok
end
# Regular/broken devbranch build
withenv(
"BUILDKITE" => "true",
"BUILDKITE_BRANCH" => "master",
"BUILDKITE_PULL_REQUEST" => "false",
"BUILDKITE_TAG" => nothing,
"DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
) do
cfg = Documenter.Buildkite()
d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
devbranch="master", devurl="hello-world", push_preview=true)
@test d.all_ok
@test d.subfolder == "hello-world"
@test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
@test d.branch == "gh-pages"
d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
devbranch="not-master", devurl="hello-world", push_preview=true)
@test !d.all_ok
@test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
end
# Regular pull request build
withenv("BUILDKITE" => "true",
"BUILDKITE_BRANCH" => "something",
"BUILDKITE_PULL_REQUEST" => "42",
"BUILDKITE_TAG" => nothing,
"DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
) do
cfg = Documenter.Buildkite()
d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
devbranch="master", devurl="hello-world", push_preview=true)
@test d.all_ok
@test d.subfolder == "previews/PR42"
@test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
@test d.branch == "gh-pages"
d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
devbranch="master", devurl="hello-world", push_preview=false)
@test !d.all_ok
@test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
end
# Missing/broken environment variables
withenv(
"BUILDKITE" => "true",
"BUILDKITE_BRANCH" => "master",
"BUILDKITE_PULL_REQUEST" => "false",
"BUILDKITE_TAG" => "v1.2.3",
"DOCUMENTER_KEY" => nothing,
) do
cfg = Documenter.Buildkite()
d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
devbranch="master", devurl="hello-world", push_preview=false)
@test !d.all_ok
end
end end

struct CustomConfig <: Documenter.DeployConfig end
Documenter.deploy_folder(::CustomConfig; kwargs...) = Documenter.DeployDecision(; all_ok = true, subfolder = "v1.2.3")
struct BrokenConfig <: Documenter.DeployConfig end
Expand Down