Skip to content

Commit d76784e

Browse files
Add support for Woodpecker CI 1.x and 2.x (#2339)
1 parent 3341026 commit d76784e

File tree

4 files changed

+648
-223
lines changed

4 files changed

+648
-223
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* Documenter now warns when it encounters invalid keys in the various key-value at-blocks. ([#2306], [#2324])
1313
* File sizes are now expressed in more human-readable format. ([#2272], [#2344])
1414
* Documenter now uses [Git.jl](https://github.com/JuliaVersionControl/Git.jl) (as opposed to the system's `git` binary) for Git operations. ([#2348])
15+
* Woodpecker CI 1.x and 2.x are now also supported. ([#2337], [#2335], [#2339])
1516

1617
### Fixed
1718

@@ -1750,6 +1751,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17501751
[#2327]: https://github.com/JuliaDocs/Documenter.jl/issues/2327
17511752
[#2329]: https://github.com/JuliaDocs/Documenter.jl/issues/2329
17521753
[#2330]: https://github.com/JuliaDocs/Documenter.jl/issues/2330
1754+
[#2335]: https://github.com/JuliaDocs/Documenter.jl/issues/2335
1755+
[#2337]: https://github.com/JuliaDocs/Documenter.jl/issues/2337
1756+
[#2339]: https://github.com/JuliaDocs/Documenter.jl/issues/2339
17531757
[#2344]: https://github.com/JuliaDocs/Documenter.jl/issues/2344
17541758
[#2348]: https://github.com/JuliaDocs/Documenter.jl/issues/2348
17551759
[JuliaLang/julia#29344]: https://github.com/JuliaLang/julia/issues/29344

docs/src/man/hosting.md

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -437,18 +437,35 @@ This access token should be added to Woodpecker CI as a secret named as
437437
uppercase environment variables to your pipeline. Next, create a new pipeline
438438
configuration file called `.woodpecker.yml` with the following contents:
439439

440-
```yaml
441-
pipeline:
442-
docs:
443-
when:
444-
branch: main # update to match your development branch
445-
image: julia
446-
commands:
447-
- julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
448-
- julia --project=docs/ docs/make.jl
449-
secrets: [ project_access_token ] # access token is a secret
450-
451-
```
440+
- Woodpecker 0.15.x and pre-1.0.0
441+
442+
```yaml
443+
pipeline:
444+
docs:
445+
when:
446+
branch: main # update to match your development branch
447+
image: julia
448+
commands:
449+
- julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
450+
- julia --project=docs/ docs/make.jl
451+
secrets: [ project_access_token ] # access token is a secret
452+
453+
```
454+
455+
- Woodpecker 1.0.x and onwards
456+
457+
```yaml
458+
steps:
459+
docs:
460+
when:
461+
branch: main # update to match your development branch
462+
image: julia
463+
commands:
464+
- julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
465+
- julia --project=docs/ docs/make.jl
466+
secrets: [ project_access_token ] # access token is a secret
467+
468+
```
452469

453470
This will pull an image of julia from docker and run the following commands from
454471
`commands:` which instantiates the project for development and then runs the `make.jl`

src/deployconfig.jl

Lines changed: 110 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -854,12 +854,25 @@ documenter_key(::Buildkite) = ENV["DOCUMENTER_KEY"]
854854
#################
855855
# Woodpecker CI #
856856
#################
857-
858857
"""
859858
Woodpecker <: DeployConfig
860859
861860
Implementation of `DeployConfig` for deploying from Woodpecker CI.
862861
862+
## Woodpecker 1.0.0 and onwards
863+
864+
The following environmental variables are built-in from the Woodpecker pipeline
865+
influences how `Documenter` works.
866+
867+
- `CI_REPO`: must match the full name of the repository <owner>/<name> e.g. `JuliaDocs/Documenter.jl`
868+
- `CI_PIPELINE_EVENT`: must be set to `push`, `tag`, `pull_request`, and `deployment`
869+
- `CI_COMMIT_REF`: must match the `devbranch` keyword to [`deploydocs`](@ref), alternatively correspond to a git tag.
870+
- `CI_COMMIT_TAG`: must match to a tag.
871+
- `CI_COMMIT_PULL_REQUEST`: must return the PR number.
872+
- `CI_FORGE_URL`: env var to build the url to be used for authentication.
873+
874+
## Woodpecker 0.15.x and pre-1.0.0
875+
863876
The following environmental variables are built-in from the Woodpecker pipeline
864877
influences how `Documenter` works:
865878
- `CI_REPO`: must match the full name of the repository <owner>/<name> e.g. `JuliaDocs/Documenter.jl`
@@ -868,46 +881,65 @@ influences how `Documenter` works:
868881
- `CI_COMMIT_REF`: must match the `devbranch` keyword to [`deploydocs`](@ref), alternatively correspond to a git tag.
869882
- `CI_COMMIT_TAG`: must match to a tag.
870883
- `CI_COMMIT_PULL_REQUEST`: must return the PR number.
871-
- `CI_REPO_OWNER`: must return the value of the repo owner. Real names are not necessary.
884+
## Documenter Specific Environmental Variables
872885
873-
The following user-defined environmental variables influences how `Documenter` works:
874-
- `PROJECT_ACCESS_TOKEN`: user generated access token from a forge e.g. GitHub, GitLab, Codeberg to be used as a secret.
875-
- `FORGE_URL`: user-defined env var to be used for authentication. Optional.
886+
- `DOCUMENTER_KEY`: must contain the Base64-encoded SSH private key for the
887+
repository. This variable should be somehow set in the CI environment, e.g.,
888+
provisioned by an agent environment plugin.
876889
877-
User can define the `FORGE_URL` variable and add it to their Woodpecker pipeline definition:
890+
Lastly, another environment-variable used for authentication is
891+
the `PROJECT_ACCESS_TOKEN` which is an access token you defined by
892+
the forge you use e.g. GitHub, GitLab, Codeberg, and other gitea
893+
instances. Check their documentation on how to create an access token.
894+
This access token should be then added as a secret as documented in
895+
<https://woodpecker-ci.org/docs/usage/secrets>.
896+
897+
# Example Pipeline Syntax
898+
899+
## 1.0.0 and onwards
878900
879-
Example `.woodpecker.yml`
880901
```yaml
881-
pipeline:
882-
docs:
883-
image: julia
884-
environment:
885-
- FORGE_URL=github.com
886-
...
902+
labels:
903+
platform: linux/amd64
904+
905+
steps:
906+
docs:
907+
when:
908+
branch:
909+
- main
910+
image: opensuse/tumbleweed
911+
commands:
912+
- zypper --non-interactive install openssh juliaup git
913+
- /usr/bin/julia --project=docs/ --startup-file=no --history-file=no -e "import Pkg; Pkg.instantiate()"
914+
- /usr/bin/julia --project=docs/ --startup-file=no --history-file=no -e docs/make.jl
915+
secrets: [ documenter_key, project_access_token ]
887916
```
888917
889-
Or
918+
## 0.15.x and pre-1.0.0
890919
891920
```yaml
921+
platforms: linux/amd64
922+
892923
pipeline:
893-
docs:
894-
image: julia
895-
commands:
896-
- export FORGE_URL=github.com
897-
...
924+
docs:
925+
when:
926+
branch:
927+
- main
928+
image: opensuse/tumbleweed
929+
commands:
930+
- zypper --non-interactive install openssh juliaup git
931+
- /usr/bin/julia --project=docs/ --startup-file=no --history-file=no -e "import Pkg; Pkg.instantiate()"
932+
- /usr/bin/julia --project=docs/ --startup-file=no --history-file=no -e docs/make.jl
933+
secrets: [ documenter_key, project_access_token ]
898934
```
899935
900-
More about pipeline syntax is documented here: <https://woodpecker-ci.org/docs/usage/workflow-syntax>
901-
902-
Lastly, another environment-variable used for authentication is
903-
the `PROJECT_ACCESS_TOKEN` which is an access token you defined by
904-
the forge you use e.g. GitHub, GitLab, Codeberg, and other gitea
905-
instances. Check their documentation on how to create an access token.
906-
This access token should be then added as a secret as documented in
907-
<https://woodpecker-ci.org/docs/usage/secrets>.
936+
More about pipeline syntax is documented here:
937+
- 0.15.x <https://woodpecker-ci.org/docs/0.15/usage/pipeline-syntax>
938+
- 1.0.0 and onwards <https://woodpecker-ci.org/docs/1.0/usage/pipeline-syntax>
939+
- 2.0.0 <https://woodpecker-ci.org/docs/usage/workflow-syntax>
908940
"""
909941
struct Woodpecker <: DeployConfig
910-
woodpecker_repo_link::String
942+
woodpecker_ci_version::VersionNumber
911943
woodpecker_forge_url::String
912944
woodpecker_repo::String
913945
woodpecker_tag::String
@@ -922,16 +954,40 @@ Initialize woodpecker environment-variables. Further info of
922954
environment-variables used are in <https://woodpecker-ci.org/docs/usage/environment>
923955
"""
924956
function Woodpecker()
925-
woodpecker_repo_link = get(ENV, "CI_REPO_LINK", "")
926-
m = match(r"https?:\/\/(?:.+\.)*(.+\..+?)\/", woodpecker_repo_link)
927-
# Get the forge URL, otherwise, if the value is `nothing`,
928-
# Then use the woodpecker_repo_link
929-
woodpecker_forge_url = isnothing(m) ? woodpecker_repo_link : m.captures[1]
930-
woodpecker_tag = get(ENV, "CI_COMMIT_TAG", "")
931-
woodpecker_repo = get(ENV, "CI_REPO", "") # repository full name <owner>/<name>
932-
woodpecker_event_name = get(ENV, "CI_BUILD_EVENT", "") # build event (push, pull_request, tag, deployment)
933-
woodpecker_ref = get(ENV, "CI_COMMIT_REF", "") # commit ref
934-
return Woodpecker(woodpecker_repo_link, woodpecker_forge_url, woodpecker_repo, woodpecker_tag, woodpecker_event_name, woodpecker_ref)
957+
m = match(r"(next)?-*", ENV["CI_SYSTEM_VERSION"])
958+
if !isnothing(m.captures[1])
959+
@warn """You are currently using an unreleased version of Woodpecker
960+
CI. Creating dummy version to temporarily resolve the issue."""
961+
woodpecker_ci_version = v"1000"
962+
else
963+
woodpecker_ci_version = VersionNumber(ENV["CI_SYSTEM_VERSION"])
964+
@warn "Current Woodpecker version is $(woodpecker_ci_version). Make sure this is correct."
965+
if ENV["CI"] == "drone" && (v"1.0.0" > VersionNumber(ENV["CI_SYSTEM_VERSION"]) >= v"0.15.0")
966+
@warn """Woodpecker prior version 1.0.0 is backward compatible to Drone
967+
but *there will be breaking changes in the future*. Please update
968+
to a newer version """
969+
end
970+
end
971+
972+
# Woodpecker skipped 0.16.x and went to 1.0.0 and onwards
973+
# Woodpecker integration on Documenter.jl started with Woodpecker 0.15.0
974+
if v"1.0.0" > woodpecker_ci_version >= v"0.15.0"
975+
woodpecker_repo_link = get(ENV, "CI_REPO_LINK", "")
976+
m = match(r"(https?:\/\/?:.+\.)*(.+\..+?)\/", woodpecker_repo_link)
977+
woodpecker_forge_url = !isnothing(m) ? m.captures[2] : ""
978+
woodpecker_tag = get(ENV, "CI_COMMIT_TAG", "")
979+
woodpecker_repo = get(ENV, "CI_REPO", "")
980+
woodpecker_event_name = get(ENV, "CI_BUILD_EVENT", "")
981+
woodpecker_ref = get(ENV, "CI_COMMIT_REF", "")
982+
return Woodpecker(woodpecker_ci_version, woodpecker_forge_url, woodpecker_repo, woodpecker_tag, woodpecker_event_name, woodpecker_ref)
983+
else
984+
woodpecker_forge_url = get(ENV, "CI_FORGE_URL", "")
985+
woodpecker_tag = get(ENV, "CI_COMMIT_TAG", "")
986+
woodpecker_repo = get(ENV, "CI_REPO", "") # repository full name <owner>/<name>
987+
woodpecker_event_name = get(ENV, "CI_PIPELINE_EVENT", "") # build event (push, pull_request, tag, deployment)
988+
woodpecker_ref = get(ENV, "CI_COMMIT_REF", "") # commit ref
989+
return Woodpecker(woodpecker_ci_version, woodpecker_forge_url, woodpecker_repo, woodpecker_tag, woodpecker_event_name, woodpecker_ref)
990+
end
935991
end
936992

937993
function deploy_folder(
@@ -943,7 +999,7 @@ function deploy_folder(
943999
devbranch,
9441000
push_preview,
9451001
devurl,
946-
tag_prefix = "",
1002+
tag_prefix="",
9471003
kwargs...)
9481004
io = IOBuffer()
9491005
all_ok = true
@@ -957,20 +1013,24 @@ function deploy_folder(
9571013

9581014
println(io, "Deployment criteria for deploying $(build_type) build from Woodpecker-CI")
9591015
## The deploydocs' repo should match CI_REPO
960-
#
961-
repo_link_ok = !isempty(cfg.woodpecker_repo_link) # if repo link is an empty string then it is not valid
962-
all_ok &= repo_link_ok
1016+
9631017
forge_url_ok = !isempty(cfg.woodpecker_forge_url) # if the forge url is an empty string, it is not a valid url
9641018
all_ok &= forge_url_ok
9651019

9661020
repo_ok = occursin(cfg.woodpecker_repo, repo)
9671021
all_ok &= repo_ok
9681022
println(io, "- $(marker(repo_ok)) ENV[\"CI_REPO\"]=\"$(cfg.woodpecker_repo)\" occursin in repo=\"$(repo)\"")
9691023

1024+
ci_event_env_name = if haskey(ENV, "CI_PIPELINE_EVENT")
1025+
"ENV[\"CI_PIPELINE_EVENT\"]"
1026+
elseif haskey(ENV, "CI_BUILD_EVENT")
1027+
"ENV[\"CI_BUILD_EVENT\"]"
1028+
end
1029+
9701030
if build_type === :release
9711031
event_ok = in(cfg.woodpecker_event_name, ["push", "pull_request", "deployment", "tag"])
9721032
all_ok &= event_ok
973-
println(io, "- $(marker(event_ok)) ENV[\"CI_BUILD_EVENT\"]=\"$(cfg.woodpecker_event_name)\" is \"push\", \"deployment\" or \"tag\"")
1033+
println(io, "- $(marker(event_ok)) $(ci_event_env_name)=\"$(cfg.woodpecker_event_name)\" is \"push\", \"deployment\" or \"tag\"")
9741034
tag_nobuild = version_tag_strip_build(cfg.woodpecker_tag; tag_prefix)
9751035
tag_ok = tag_nobuild !== nothing
9761036
all_ok &= tag_ok
@@ -984,7 +1044,7 @@ function deploy_folder(
9841044
## Do not deploy for PRs
9851045
event_ok = in(cfg.woodpecker_event_name, ["push", "pull_request", "deployment", "tag"])
9861046
all_ok &= event_ok
987-
println(io, "- $(marker(event_ok)) ENV[\"CI_BUILD_EVENT\"]=\"$(cfg.woodpecker_event_name)\" is \"push\", \"deployment\", or \"tag\"")
1047+
println(io, "- $(marker(event_ok)) $(ci_event_env_name)=\"$(cfg.woodpecker_event_name)\" is \"push\", \"deployment\", or \"tag\"")
9881048
## deploydocs' devbranch should match the current branch
9891049
m = match(r"^refs\/heads\/(.*)$", cfg.woodpecker_ref)
9901050
branch_ok = (m === nothing) ? false : String(m.captures[1]) == devbranch
@@ -1001,11 +1061,11 @@ function deploy_folder(
10011061
pr_number2 = tryparse(Int, get(ENV, "CI_COMMIT_PULL_REQUEST", nothing) === nothing ? "" : ENV["CI_COMMIT_PULL_REQUEST"])
10021062
# Check if both are Ints. If both are Ints, then check if they are equal, otherwise, return false
10031063
pr_numbers_ok = all(x -> x isa Int, [pr_number1, pr_number2]) ? (pr_number1 == pr_number2) : false
1004-
is_pull_request_ok = get(ENV, "CI_BUILD_EVENT", "") == "pull_request"
1064+
is_pull_request_ok = cfg.woodpecker_event_name == "pull_request"
10051065
pr_ok = pr_numbers_ok == is_pull_request_ok
10061066
all_ok &= pr_ok
10071067
println(io, "- $(marker(pr_numbers_ok)) ENV[\"CI_COMMIT_REF\"] corresponds to a PR")
1008-
println(io, "- $(marker(is_pull_request_ok)) ENV[\"CI_BUILD_EVENT\"] matches built type: `pull_request`")
1068+
println(io, "- $(marker(is_pull_request_ok)) $(ci_event_env_name) matches built type: `pull_request`")
10091069
btype_ok = push_preview
10101070
all_ok &= btype_ok
10111071
println(io, "- $(marker(btype_ok)) `push_preview` keyword argument to deploydocs is `true`")
@@ -1051,19 +1111,9 @@ end
10511111

10521112
authentication_method(::Woodpecker) = env_nonempty("DOCUMENTER_KEY") ? SSH : HTTPS
10531113
function authenticated_repo_url(cfg::Woodpecker)
1054-
# `cfg.woodpecker_forge_url` should be just the root of the URL e.g. github.com, gitlab.com, codeberg.org
1055-
# otherwise, it will be equal to `cfg.woodpecker_repo_link`
1056-
# If so, we just split the `http(s)://` from the string we want
1057-
# e.g. `https://github.com/JuliaDocs/Documenter.jl` to `github.com/JuliaDocs/Documenter.jl`.
1058-
if haskey(ENV, "FORGE_URL")
1059-
return "https://$(ENV["CI_REPO_OWNER"]):$(ENV["PROJECT_ACCESS_TOKEN"])@$(ENV["FORGE_URL"])/$(cfg.woodpecker_repo).git"
1060-
else
1061-
if occursin(cfg.woodpecker_repo, cfg.woodpecker_forge_url)
1062-
return "https://$(ENV["CI_REPO_OWNER"]):$(ENV["PROJECT_ACCESS_TOKEN"])@$(split(cfg.woodpecker_forge_url, r"https?://")[2]).git"
1063-
else
1064-
return "https://$(ENV["CI_REPO_OWNER"]):$(ENV["PROJECT_ACCESS_TOKEN"])@$(cfg.woodpecker_forge_url)/$(cfg.woodpecker_repo).git"
1065-
end
1066-
end
1114+
# https://codeberg.org -> codeberg.org
1115+
forge_domain = split(cfg.woodpecker_forge_url, r"https?://")[2]
1116+
return "https://$(ENV["PROJECT_ACCESS_TOKEN"])@$(forge_domain)/$(cfg.woodpecker_repo).git"
10671117
end
10681118

10691119
##################
@@ -1078,11 +1128,7 @@ function auto_detect_deploy_system()
10781128
return GitLab()
10791129
elseif haskey(ENV, "BUILDKITE")
10801130
return Buildkite()
1081-
elseif get(ENV, "CI", nothing) in ["drone", "woodpecker"]
1082-
if ENV["CI"] == "drone"
1083-
@warn """Woodpecker is backward compatible to Drone
1084-
but *there will be breaking changes in the future*"""
1085-
end
1131+
elseif get(ENV, "CI", "") in ["woodpecker", "drone"]
10861132
return Woodpecker()
10871133
else
10881134
return nothing

0 commit comments

Comments
 (0)