Skip to content

Commit 116e8f0

Browse files
committed
If there is 1 artifact, don't require clicking through to it
1 parent 04c7e07 commit 116e8f0

File tree

3 files changed

+41
-27
lines changed

3 files changed

+41
-27
lines changed

spec/main_spec.cr

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ RUN_3 = 987654326
1515
JOB_1 = 9977553311
1616
JOB_2 = 9977553317
1717
ARTIFACT_1 = 87654321
18+
ARTIFACT_2 = 87654325
1819
PRIVATE_REPO = "oprypin/test-private-repo"
1920

2021
require "http"
@@ -156,7 +157,9 @@ describe "dash_by_branch" do
156157
body: %({"workflow_runs":[
157158
{"id":#{RUN_2},"event":"schedule","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/UserName/RepoName/check-suites/#{CHECK_SUITE_1}","updated_at":"2021-02-07T07:15:00Z","repository":{"full_name":"UserName/RepoName","private":false,"fork":false}}]}))
158159
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/runs/#{RUN_2}/artifacts?per_page=100").to_return(
159-
body: %({"artifacts":[{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/UserName/RepoName/actions/artifacts/#{ARTIFACT_1}"}]}))
160+
body: %({"artifacts":[
161+
{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/UserName/RepoName/actions/artifacts/#{ARTIFACT_1}"},
162+
{"id":#{ARTIFACT_2},"name":"AnotherArtifact","url":"https://api.github.com/repos/UserName/RepoName/actions/artifacts/#{ARTIFACT_2}"}]}))
160163
end
161164

162165
test do
@@ -194,12 +197,14 @@ describe "dash_by_branch" do
194197
test do
195198
WebMock.stub(:get, "https://api.github.com/repos/#{PRIVATE_REPO}/actions/workflows/SomeWorkflow.yml/runs?per_page=1&branch=SomeBranch&event=push&status=success").to_return(
196199
body: %({"workflow_runs":[
197-
{"id":#{RUN_1},"event":"push","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2020-12-19T22:22:22Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
200+
{"id":#{RUN_1},"event":"push","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2020-12-19T22:22:22Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
198201
WebMock.stub(:get, "https://api.github.com/repos/#{PRIVATE_REPO}/actions/workflows/SomeWorkflow.yml/runs?per_page=1&branch=SomeBranch&event=schedule&status=success").to_return(
199202
body: %({"workflow_runs":[
200-
{"id":#{RUN_2},"event":"schedule","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2021-02-07T07:15:00Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
203+
{"id":#{RUN_2},"event":"schedule","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2021-02-07T07:15:00Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
201204
WebMock.stub(:get, "https://api.github.com/repos/#{PRIVATE_REPO}/actions/runs/#{RUN_2}/artifacts?per_page=100").to_return(
202-
body: %({"artifacts":[{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/#{PRIVATE_REPO}/actions/artifacts/#{ARTIFACT_1}"}]}))
205+
body: %({"artifacts":[
206+
{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/#{PRIVATE_REPO}/actions/artifacts/#{ARTIFACT_1}"},
207+
{"id":#{ARTIFACT_2},"name":"AnotherArtifact","url":"https://api.github.com/repos/#{PRIVATE_REPO}/actions/artifacts/#{ARTIFACT_2}"}]}))
203208

204209
resp, body = serve("/#{PRIVATE_REPO}/workflows/SomeWorkflow/SomeBranch?h=6c9bf24563d1896f5de321ce6043413f8c75ef16")
205210
assert_canonical "https://nightly.link/#{PRIVATE_REPO}/workflows/SomeWorkflow/SomeBranch?h=6c9bf24563d1896f5de321ce6043413f8c75ef16"
@@ -248,11 +253,11 @@ describe "dash_by_run" do
248253
resp, body = serve("/uSerName/RepoName/actions/runs/#{RUN_1}")
249254
assert_canonical "https://nightly.link/UserName/RepoName/actions/runs/#{RUN_1}"
250255
assert_contents [
251-
"Repository UserName/RepoName", "Run #987654321",
252-
"Repository UserName/RepoName", "Run #987654321",
253-
"https://nightly.link/UserName/RepoName/actions/runs/987654321/SomeArtifact",
254-
"https://nightly.link/UserName/RepoName/actions/runs/987654321/SomeArtifact.zip",
255-
"https://nightly.link/UserName/RepoName/actions/runs/987654321/SomeArtifact.zip",
256+
"Repository UserName/RepoName", "Run ##{RUN_1}",
257+
"Repository UserName/RepoName", "Run ##{RUN_1}",
258+
"https://nightly.link/UserName/RepoName/actions/runs/#{RUN_1}/SomeArtifact",
259+
"https://nightly.link/UserName/RepoName/actions/runs/#{RUN_1}/SomeArtifact.zip",
260+
"https://nightly.link/UserName/RepoName/actions/runs/#{RUN_1}/SomeArtifact.zip",
256261
]
257262
assert_nofollow
258263
end
@@ -264,8 +269,8 @@ describe "dash_by_run" do
264269
resp, body = serve("/UserName/RepoName/actions/runs/#{RUN_3}")
265270
assert resp.status == HTTP::Status::NOT_FOUND
266271
assert_contents [
267-
"No artifacts found for run #987654326",
268-
"https://github.com/UserName/RepoName/actions/runs/987654326#artifacts",
272+
"No artifacts found for run ##{RUN_3}",
273+
"https://github.com/UserName/RepoName/actions/runs/#{RUN_3}#artifacts",
269274
]
270275
assert_nofollow
271276
end
@@ -275,12 +280,14 @@ describe "by_branch" do
275280
before_each do
276281
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/workflows/SomeWorkflow.yml/runs?per_page=1&branch=SomeBranch&event=push&status=success").to_return(
277282
body: %({"workflow_runs":[
278-
{"id":#{RUN_1},"event":"push","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/UserName/RepoName/check-suites/#{CHECK_SUITE_1}","updated_at":"2020-12-19T22:22:22Z","repository":{"full_name":"UserName/RepoName","private":false,"fork":false}}]}))
283+
{"id":#{RUN_1},"event":"push","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/UserName/RepoName/check-suites/#{CHECK_SUITE_1}","updated_at":"2020-12-19T22:22:22Z","repository":{"full_name":"UserName/RepoName","private":false,"fork":false}}]}))
279284
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/workflows/SomeWorkflow.yml/runs?per_page=1&branch=SomeBranch&event=schedule&status=success").to_return(
280285
body: %({"workflow_runs":[
281-
{"id":#{RUN_2},"event":"schedule","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/UserName/RepoName/check-suites/#{CHECK_SUITE_1}","updated_at":"2021-02-07T07:15:00Z","repository":{"full_name":"UserName/RepoName","private":false,"fork":false}}]}))
286+
{"id":#{RUN_2},"event":"schedule","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/UserName/RepoName/check-suites/#{CHECK_SUITE_1}","updated_at":"2021-02-07T07:15:00Z","repository":{"full_name":"UserName/RepoName","private":false,"fork":false}}]}))
282287
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/runs/#{RUN_2}/artifacts?per_page=100").to_return(
283-
body: %({"artifacts":[{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/UserName/RepoName/actions/artifacts/#{ARTIFACT_1}"}]}))
288+
body: %({"artifacts":[
289+
{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/UserName/RepoName/actions/artifacts/#{ARTIFACT_1}"},
290+
{"id":#{ARTIFACT_2},"name":"AnotherArtifact","url":"https://api.github.com/repos/UserName/RepoName/actions/artifacts/#{ARTIFACT_2}"}]}))
284291
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/artifacts/#{ARTIFACT_1}/zip").to_return(
285292
headers: HTTP::Headers{"location" => "http://example.org/download1"})
286293
end
@@ -330,12 +337,14 @@ describe "by_branch" do
330337
test do
331338
WebMock.stub(:get, "https://api.github.com/repos/#{PRIVATE_REPO}/actions/workflows/SomeWorkflow.yml/runs?per_page=1&branch=SomeBranch&event=push&status=success").to_return(
332339
body: %({"workflow_runs":[
333-
{"id":#{RUN_1},"event":"push","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2020-12-19T22:22:22Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
340+
{"id":#{RUN_1},"event":"push","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2020-12-19T22:22:22Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
334341
WebMock.stub(:get, "https://api.github.com/repos/#{PRIVATE_REPO}/actions/workflows/SomeWorkflow.yml/runs?per_page=1&branch=SomeBranch&event=schedule&status=success").to_return(
335342
body: %({"workflow_runs":[
336-
{"id":#{RUN_2},"event":"schedule","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2021-02-07T07:15:00Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
343+
{"id":#{RUN_2},"event":"schedule","workflow_id":#{WORKFLOW_1},"check_suite_url":"https://api.github.com/repos/#{PRIVATE_REPO}/check-suites/#{CHECK_SUITE_1}","updated_at":"2021-02-07T07:15:00Z","repository":{"full_name":"#{PRIVATE_REPO}","private":false,"fork":false}}]}))
337344
WebMock.stub(:get, "https://api.github.com/repos/#{PRIVATE_REPO}/actions/runs/#{RUN_2}/artifacts?per_page=100").to_return(
338-
body: %({"artifacts":[{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/#{PRIVATE_REPO}/actions/artifacts/#{ARTIFACT_1}"}]}))
345+
body: %({"artifacts":[
346+
{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/#{PRIVATE_REPO}/actions/artifacts/#{ARTIFACT_1}"},
347+
{"id":#{ARTIFACT_2},"name":"AnotherArtifact","url":"https://api.github.com/repos/#{PRIVATE_REPO}/actions/artifacts/#{ARTIFACT_2}"}]}))
339348
WebMock.stub(:get, "https://api.github.com/repos/#{PRIVATE_REPO}/actions/artifacts/#{ARTIFACT_1}/zip").to_return(
340349
headers: HTTP::Headers{"location" => "http://example.org/download2"})
341350

@@ -358,29 +367,29 @@ end
358367

359368
describe "by_run" do
360369
before_each do
361-
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/runs/#{RUN_2}/artifacts?per_page=100").to_return(
370+
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/runs/#{RUN_1}/artifacts?per_page=100").to_return(
362371
body: %({"artifacts":[{"id":#{ARTIFACT_1},"name":"SomeArtifact","url":"https://api.github.com/repos/UserName/RepoName/actions/artifacts/#{ARTIFACT_1}"}]}))
363372
WebMock.stub(:get, "https://api.github.com/repos/username/reponame/actions/artifacts/#{ARTIFACT_1}/zip").to_return(
364373
headers: HTTP::Headers{"location" => "http://example.org/download1"})
365374
end
366375

367376
test do
368-
resp, body = serve("/UserName/RepoName/actions/runs/#{RUN_2}/SomeArtifact")
369-
assert_canonical "https://nightly.link/UserName/RepoName/actions/runs/#{RUN_2}/SomeArtifact"
377+
resp, body = serve("/UserName/RepoName/actions/runs/#{RUN_1}/SomeArtifact")
378+
assert_canonical "https://nightly.link/UserName/RepoName/actions/runs/#{RUN_1}/SomeArtifact"
370379
assert_contents [
371-
"Repository UserName/RepoName", "Run #987654324 | Artifact SomeArtifact",
380+
"Repository UserName/RepoName", "Run ##{RUN_1} | Artifact SomeArtifact",
372381
] * 2 + [
373-
"https://nightly.link/UserName/RepoName/actions/runs/#{RUN_2}/SomeArtifact.zip",
382+
"https://nightly.link/UserName/RepoName/actions/runs/#{RUN_1}/SomeArtifact.zip",
374383
"https://nightly.link/UserName/RepoName/actions/artifacts/#{ARTIFACT_1}.zip",
375384
].flat_map { |s| [s, s] } + [
376385
"http://example.org/download1",
377-
"https://github.com/UserName/RepoName/actions/runs/#{RUN_2}#artifacts",
386+
"https://github.com/UserName/RepoName/actions/runs/#{RUN_1}#artifacts",
378387
]
379388
assert_nofollow
380389
end
381390

382391
test "redirect" do
383-
resp, body = serve("/UserName/RepoName/actions/runs/#{RUN_2}/SomeArtifact.zip")
392+
resp, body = serve("/UserName/RepoName/actions/runs/#{RUN_1}/SomeArtifact.zip")
384393
assert_redirect "http://example.org/download1"
385394
end
386395
end
@@ -425,8 +434,8 @@ describe "by_job" do
425434
resp, body = serve("/uSerName/RepoName/runs/#{JOB_1}")
426435
assert_canonical "https://nightly.link/uSerName/RepoName/runs/#{JOB_1}"
427436
assert_contents [
428-
"Repository uSerName/RepoName", "Job #9977553311",
429-
"Repository uSerName/RepoName", "Job #9977553311",
437+
"Repository uSerName/RepoName", "Job ##{JOB_1}",
438+
"Repository uSerName/RepoName", "Job ##{JOB_1}",
430439
"https://nightly.link/uSerName/RepoName/runs/#{JOB_1}.txt",
431440
"http://example.org/download1",
432441
"https://github.com/uSerName/RepoName/runs/#{JOB_1}",

src/nightly_link.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,10 @@ class NightlyLink
333333
repo_owner: repo_owner, repo_name: repo_name, workflow: workflow.rchop(".yml"), branch: branch, artifact: art.name
334334
)), art.name, h: h)
335335
end
336+
if links.size == 1
337+
raise HTTPException.redirect(links[0].url)
338+
end
339+
336340
title = {"Repository #{repo_owner}/#{repo_name}", "Workflow #{workflow} | Branch #{branch}"}
337341
canonical = abs_url(NightlyLink.gen_dash_by_branch(
338342
repo_owner: repo_owner, repo_name: repo_name, workflow: workflow.rchop(".yml"), branch: branch

templates/controls.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ <h2>Paste a GitHub link, get a nightly.link!</h2>
2525
<details>
2626
<summary>Link to a repository's latest artifact</summary>
2727
<p>Insert the GitHub URL of a workflow file that uses <a target="_blank" href="https://github.com/actions/upload-artifact#readme">actions/upload-artifact</a>.<br/>
28-
Example: <a class="example" target="_blank" href="<%= HTML.escape(example_workflow) %>"><%= HTML.escape(example_workflow) %></a></p>
28+
Example: <a class="example" target="_blank" href="<%= HTML.escape(example_workflow) %>"><%= HTML.escape(example_workflow) %></a><br>
29+
Note that the <i>branch</i> which you're on also matters.</p>
2930
<p>Following this form (and having selected the "<%= example_art %>" artifact), you will end up at<br><a rel="nofollow" href="<%= example_dest %>"><%= example_dest %></a> [<a rel="nofollow" href="<%= example_dest %>.zip">.zip</a>]<br>
3031
which is a link that always downloads the latest artifact from a <u>succeeding</u> run on that <u>repo</u>+<u>workflow</u>+<u>branch</u>.</p>
3132
<p>If you have several workflows or branches, you can adapt the URL by hand in a predictable way.</p>

0 commit comments

Comments
 (0)