feat: Add Github action artifact download support#816
Conversation
- required flags - Pattern type for Name pattern - Unzip default false - RunSelector static class - GithubCommand parent
Changed name-pattern to artifact-pattern
|
You can either pass a specific workflow run id, or a workflow name, along with organisation/repository. Command then queries actions, selecting either the latest succesful action for a specific workflow, or the already provided workflow id. Then pattern matches against artifacts and downloads the matching artifact. Usage: mc-image-helper github download-artifact [-h] [--overwrite] [--unzip]
--artifact-pattern=<artifactPattern> [-o=<outputDirectory>]
(--workflow=ID|FILE | --run-id=ID) [[--use-http2] [--wiretap]] org/repo
Download an artifact from a successful GitHub Actions workflow
org/repo
--artifact-pattern=<artifactPattern>
Regular expression that must match exactly one
artifact name
-h, --help
-o, --output-directory=<outputDirectory>
Output directory of downloaded artifact
--overwrite Overwrite existing files when extracing zip
--run-id=ID Query this specific workflow run to download an
artifact
--unzip Extract the downloaded artifact
--use-http2 Whether to use HTTP/2.
Default: true
Env: FETCH_USE_HTTP2
--wiretap Whether to enable Reactor Netty wiretap logging.
Make sure to set logging level to trace.
Default: false
Env: FETCH_WIRETAP
--workflow=ID|FILE Query this workflow for the latest successful run to
download an artifactFor example, with @SgtMate use case, the below queries the latest successful daily build, downloading the Java17 server arifact, and extracting it to ./gtnh GH_TOKEN="$(gh auth token)" ./gradlew run --args="github download-artifact --workflow daily-modpack-build.yml --name-pattern='GTNH-daily-\d{4}-\d{2}-\d{2}\+\d+-server-java17-25\.zip' -o=./gtnh --unzip GTNewHorizons/DreamAssemblerXXL"
|
|
this looks great! this is exactly what i need. one thing i want to add tho is the |
When you want to change output name, do you want the file still as a zip i assume? And the zip renamed? Or whatever format the Artifact is |
|
So what I need is for the command to return the filename that was downloaded. (independent of if its unpacked or not). |
|
This looks great @harrisonablack and I like @SgtMate 's request. |
|
another question, just so i understand. is it correct, that the gh token is not handed to the command directly? so i need to set it in env? |
|
The token can be passed either way: however, within itzg/minecraft-server the expectation is that the user has set the container env var to allow for token access across the whole startup. |
|
@itzg ok get it, then i will adhere to the existing processes. |
|
Wait, that's bit of a usability problem. Users installing GTNH aren't expecting to need a GitHub token. @harrisonablack are you certain the APIs used need authenticated access? |
|
@itzg thats fine, I'll cleary state this in the addition to the documentation. |
Yes, when i remove the null token check, and don't set env, command fails with a 401. I believe its only the Artifact download endpoint that requires auth [mc-image-helper] 23:18:25.773 ERROR : 'download-artifact' command failed. Version is ???: FailedRequestException: HTTP request of https://api.github.com/repos/GTNewHorizons/DreamAssemblerXXL/actions/artifacts/8398696458/zip failed with 401 Unauthorized: Trying to retrieve file./gradlew run --args="github download-artifact --workflow daily-modpack-build.yml --artifact-pattern='GTNH-daily-\d{4}-\d{2}-\d{2}\+\d+-server-java17-25\.zip' -o=./gtnh --unzip GTNewHorizons/DreamAssemblerXXL" |
|
https://docs.github.com/en/rest/actions/artifacts?apiVersion=2026-03-10#download-an-artifact
|
|
another thing i need to add to my request is some kind of dry-run functionality. where only the resulting download candidate is returned without downloading it. I need this to check if an update is even required once the container is restarted. Currently im just comparing the old and new filename. This would greatly help in reducing unneeded downloads. @harrisonablack you think you can implement this with githubs given api? |
|
It's almost like it needs a "skip existing" like the
|
@SgtMate My thought process is yes, but what are we trying to do? What level of automation of the process do we want to reach? If you want to automate updating / installing daily builds of GTNH, i would lean towards a manifest similar to Paper, where when the server is installed, a file is created that states which version is installed. Then when we go to restart the container, we can check for a new build and can compare artifact names / dates before downloading. If we then automate isntalling / updating, my next questions are then GTNH specific; which files are safe to replace when updating a server, and which files do we need to keep? I'm not overly familiar with Modpacks / Modpack servers. I would lean more towards implementing a But i digress, yes, i can add another function / command argument to return the name of the artifact only |
I did add an |
… exists Previously if the output directory already existed, the log.error would be triggered, however proceces failed to create directory as directory already existed
I gently suggested that too 😉 itzg/docker-minecraft-server#4141 (comment) Seriously though, @SgtMate maybe you could provide some pseudo code or a draft PR to show where the new command fits in and what input/output would be involved in conditions. |
@SgtMate As well, i'm assuming you want some machine readable format for the output? Or is human readable fine? I would look at using |
Previously, if you passed --no-download, the command would exit stating token required, however token isn't required to query the data, only to download
|
@itzg Added two arguments, if (printArtifact) {
log.info("Resolved artifact {}", candidate.block().getName());
}For example, running returns |
Bool checks would error as booleans had null value, providing default false value
|
I would like it to be consistent with https://github.com/itzg/mc-image-helper#get where it's For |
|
...unless @SgtMate you had a different intention with the skipping of download or not. |
Changed --print-artifact to --output-filename to maintain consistency, aswell as used System.out.println
|
Fixed the print command. My only concern with --skip-existing is how will it be used and when? For the GTNH instance, we will always modify the downloaded artifact to use it, unzip it for example. Then its not an easy "does this file already exist?", it comes back to the same thought of "Do we need a manifest"? Otherwise if the thought of |
|
That'll be for @SgtMate to answer 😄 |
|
oh i see I`ve cause some discussions. Ill try to adress things one by one.
I simply do a comparison of filenames from the downloaded zip file, if the name matches with the last version installed (stored in a file) the installation is skipped, if it does not match the update is triggered and if the file is missing a fresh install is triggered. Here gtnh_download_path normaly stores the download location for the download and installation step. After download and install the value $gtnh_download is stored in the file which is derived from the download.
Yes I also see this as the best solution in the longway, but as this results in more complex migration from bash scripts over to java I'd like to split this. also because i think the now requested feature will be helpfull for other contributors of the minecraft server project, I try to have this be as usefull to the overall project as possible even tho I'm focussing on the GTNH implementation.
Close, --output-filename is important for me. The thing I need in addition is a way to just get the filename of the zip I would get back to compare to the last installed version before download.
Agree, this also makes things easier to mainain from the script side same functionality same name.
No I dont use skip existing. I hope i was able to clarify all questions! Thanks for all the work you are putting in! |
|
I'm happy if @SgtMate is happy 😄 I'll proceed with code review from here. |
|
I think Im happy, if something is still missing Ill adress this in a separate issue. Lets just get things implemented for now and improve incrementally. |
Blocks on candidate fetch before command termination
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
Remove flux need Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
…idParameterException
All good! Anything else you want me to work on, just mention me in the issue or PR and I'll be there! |
Add sub-command under
GithubCommands.javato allow downloading of specific Github action artifactsrefs: #810