Skip to content
Draft
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
6 changes: 6 additions & 0 deletions Artifacts.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[hello_world]
git-tree-sha1 = "538e83d637ab07ada6d841aa2454e0d5af4e52b3"

[[hello_world.download]]
sha256 = "d81c7e810cd9d3588a7aa0aaffb9fbc8c4db6ad2bc27f8ddb8f5382b44a5a4f9"
url = "https://github.com/pat-alt/ArtifactUtils.jl/releases/download/artifacts-latest/538e83d637ab07ada6d841aa2454e0d5af4e52b3.tar.gz"
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ProgressLogging = "33c8b6b6-d38a-422a-b730-caa89a2f386c"
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
gh_cli_jll = "5d31d589-30fb-542f-b82d-10325e863e38"
ghr_jll = "07c12ed4-43bc-5495-8a2a-d5838ef8d533"

[compat]
Git = "1"
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,34 @@ file. You can also call `add_artifact!` with the `gist` result object.
```julia
julia> add_artifact!("Artifacts.toml", "hello_world", gist)
```

### Archive a directory and upload it as release

You can also create an artifact from a directory using `artifact_from_directory` and
then upload it as a tagged release with `upload_to_release`. Note that `upload_to_release`
requires login using your `GITHUB_TOKEN`, which needs to be available from the environment.

```julia
julia> using ArtifactUtils

julia> tempdir = mktempdir();

julia> write(joinpath(tempdir, "file"), "hello");

julia> artifact_id = artifact_from_directory(tempdir)
SHA1("538e83d637ab07ada6d841aa2454e0d5af4e52b3")

julia> release = upload_to_release(artifact_id)
@Info (ArtifactUtils#release_from_file#46): Uploading tarballs to pat-alt/ArtifactUtils.jl tag `artifacts-latest`
╰────────────────────────────────────────────────
Sun, 14 Jan 2024 17:05:02
--> Uploading: 538e83d637ab07ada6d841aa2454e0d5af4e52b3.tar.gz
ArtifactUtils.ReleaseUploadResult(SHA1("538e83d637ab07ada6d841aa2454e0d5af4e52b3"), "538e83d637ab07ada6d841aa2454e0d5af4e52b3.tar.gz", "/var/folders/ct/w1pc0ggd44907l8fkl8m5pdslbh6sh/T/jl_I38b3Z/538e83d637ab07ada6d841aa2454e0d5af4e52b3.tar.gz", "https://github.com/pat-alt/ArtifactUtils.jl/releases/download/artifacts-latest/538e83d637ab07ada6d841aa2454e0d5af4e52b3.tar.gz", "d81c7e810cd9d3588a7aa0aaffb9fbc8c4db6ad2bc27f8ddb8f5382b44a5a4f9", "artifacts-latest")
```

Simply call the `add_artifact!` with the `release` result object.

```julia
julia> add_artifact!("Artifacts.toml", "hello_world", release)
```
5 changes: 4 additions & 1 deletion src/ArtifactUtils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ using Base: SHA1
using SHA
using Downloads: download

export add_artifact!, artifact_from_directory, upload_to_gist, upload_all_to_gist!
export add_artifact!, artifact_from_directory
export upload_to_gist, upload_all_to_gist!, upload_to_release

include("utils.jl")
include("gistutils.jl")
Expand Down Expand Up @@ -298,6 +299,8 @@ function print_artifact_entry(
TOML.print(io, dict; sorted = true)
end

include("upload_to_release.jl")

function Base.show(io::IO, ::MIME"text/plain", gist::GistUploadResult)
print(io, upload_to_gist, "(")
show(io, gist.artifact_id)
Expand Down
28 changes: 28 additions & 0 deletions src/release_utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function release_from_file(filepath::AbstractString; tag::AbstractString)

@assert isfile(filepath)

# Get the repo name from the git remote url
if !haskey(ENV, "GITHUB_TOKEN")
@warn "For automatic github deployment, need GITHUB_TOKEN. Not found in ENV, attemptimg global git config."
end

origin_url = strip(chomp(read(`git config --get remote.origin.url`, String)))
deploy_repo = "$(basename(dirname(origin_url)))/$(basename(origin_url))"
deploy_repo = replace(deploy_repo, ".git" => "")

# Upload tarballs to a special github release
@info("Uploading tarballs to $(deploy_repo) tag `$(tag)`")

ghr() do ghr_exe
println(
readchomp(
`$ghr_exe -replace -u $(dirname(deploy_repo)) -r $(basename(deploy_repo)) $(tag) $(filepath)`,
),
)
end

tarball_url = "https://github.com/$(deploy_repo)/releases/download/$(tag)/$(basename(filepath))"

return tarball_url
end
117 changes: 117 additions & 0 deletions src/upload_to_release.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using ghr_jll

struct ReleaseUploadResult
artifact_id::SHA1
filename::String
localpath::Union{String,Nothing}
url::String
sha256::String
tag::String
end

include("release_utils.jl")

"""
upload_to_release(
artifact_id::SHA1,
[tarball];
tag::AbstractString="artifacts-latest",
honor_overrides = false,
# Following options are aviailable only when `tarball` is not specified:
name::AbstractString = "\$artifact_id.tar.gz",
extension::AbstractString = ".tar.gz",
) -> release

Create an artifact archive at path `tarball` (or in a temporary location) and upload it to
release. The returned value `release` can be passed to `add_artifact!`.

# Extended help

## Examples
```julia
using ArtifactUtils
add_artifact!("Artifact.toml", "name", upload_to_release(artifact_from_directory("source")))
```

creates an artifact from files in the `"source"` directory, uploads it to a release, and then
adds it to `"Artifact.toml"` with the name `"name"`.

## Keyword Arguments
- `tag`: the tag of the release to upload to
- `name`: name of the archive file, including file extension
- `extension`: file extension of the tarball. It can be used for specifying the compression
method.
- `honor_overrides`: see `Pkg.Artifacts.archive_artifact`
"""
function upload_to_release end

function upload_to_release(
artifact_id::SHA1,
tarball::AbstractString;
tag::AbstractString="artifacts-latest",
archive_options...,
)
mkpath(dirname(tarball))
archive_artifact(artifact_id, tarball; archive_options...)
sha256 = sha256sum(tarball)
url = release_from_file(tarball; tag=tag)
return ReleaseUploadResult(
artifact_id,
basename(tarball),
abspath(tarball),
url,
sha256,
tag,
)
end

function upload_to_release(
artifact_id::SHA1;
name::Union{AbstractString,Nothing}=nothing,
extension::Union{AbstractString,Nothing}=nothing,
options...,
)
if name !== nothing && extension !== nothing
error(
"Options `name` and `extension` are mutually exclusive. Got: name = ",
name,
" extension = ",
extension,
)
end

tarball = if name === nothing
string(artifact_id, something(extension, ".tar.gz"))
else
name
end

return mktempdir() do dir
upload_to_release(artifact_id, joinpath(dir, tarball); options...)
end
end

"""
add_artifact!(
artifacts_toml::String,
name::String,
release::ReleaseUploadResult;
options...,
)

Extends the `add_artifact!` function to `ReleaseUploadResult`.
"""
function add_artifact!(
artifacts_toml::String,
name::String,
release::ReleaseUploadResult;
options...,
)
bind_artifact!(
artifacts_toml,
name,
release.artifact_id;
download_info=[(release.url, release.sha256)],
options...,
)
end