Skip to content

Commit 51523be

Browse files
committed
Split in two commands and adapt tests
1 parent 973a085 commit 51523be

File tree

21 files changed

+169
-125
lines changed

21 files changed

+169
-125
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
working-directory: sbt-plugin
1616
steps:
1717
- uses: actions/checkout@v3
18-
- uses: coursier/setup-action@v1.2.0-M3
18+
- uses: coursier/setup-action@v1.3.5
1919
with:
2020
apps: scalafmt sbt
2121
- run: scalafmt --test
@@ -43,7 +43,7 @@ jobs:
4343
jvm: ${{ matrix.jvm }}
4444
apps: sbt
4545
- run: sbt test
46-
- run: sbt "scripted dependency-manifest/*"
46+
- run: sbt "scripted dependency-manifest/* generate-snapshot/*"
4747
- run: sbt "scripted submit-snapshot/*"
4848
if: github.event_name == 'push' || github.event.pull_request.head.repo.owner.login == 'scalacenter'
4949

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sbt-plugin/src/main/contraband/input.contra

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ enum OnFailure {
88
warning
99
}
1010

11-
## Input of the githubSubmitDependencyGraph command
12-
type SubmitInput {
11+
## Input of the githubGenerateSnapshot command
12+
type DependencySnapshotInput {
1313
onResolveFailure: ch.epfl.scala.OnFailure
1414

1515
## A set of modules to ignore.

sbt-plugin/src/main/scala/ch/epfl/scala/GithubDependencyGraphPlugin.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
2727
.map(_.toConfigRef)
2828

2929
object autoImport {
30-
val githubSubmitInputKey: AttributeKey[SubmitInput] = AttributeKey("githubSubmitInput")
30+
val githubDependencySnapshotInputKey: AttributeKey[DependencySnapshotInput] = AttributeKey("githubSubmitInput")
3131
val githubBuildFile: AttributeKey[githubapi.FileInfo] = AttributeKey("githubBuildFile")
3232
val githubManifestsKey: AttributeKey[Map[String, githubapi.Manifest]] = AttributeKey("githubDependencyManifests")
3333
val githubProjectsKey: AttributeKey[Seq[ProjectRef]] = AttributeKey("githubProjectRefs")
34+
val githubSnapshotFileKey: AttributeKey[File] = AttributeKey("githubSnapshotFile")
35+
3436
val githubDependencyManifest: TaskKey[Option[githubapi.Manifest]] = taskKey(
3537
"The dependency manifest of the project"
3638
)
@@ -90,7 +92,7 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
9092
}
9193

9294
private def includeProject(projectRef: ProjectRef, state: State, logger: Logger): Boolean = {
93-
val ignoredModules = state.attributes(githubSubmitInputKey).ignoredModules
95+
val ignoredModules = state.attributes(githubDependencySnapshotInputKey).ignoredModules
9496
val moduleName = getModuleName(projectRef, state)
9597
val ignored = ignoredModules.contains(moduleName)
9698
if (!ignored) logger.info(s"Including dependency graph of $moduleName")
@@ -120,7 +122,7 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
120122
val thisProject = Keys.thisProject.value
121123
val internalConfigurationMap = Keys.internalConfigurationMap.value
122124

123-
val inputOpt = state.get(githubSubmitInputKey)
125+
val inputOpt = state.get(githubDependencySnapshotInputKey)
124126
val buildFileOpt = state.get(githubBuildFile)
125127

126128
val onResolveFailure = inputOpt.flatMap(_.onResolveFailure)
@@ -198,7 +200,7 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
198200
else DependencyScope.development
199201
val metadata = Map("config" -> JString(configRef.name))
200202
val node = DependencyNode(packageUrl, metadata, Some(relationship), Some(scope), dependencies)
201-
(moduleRef -> node)
203+
moduleRef -> node
202204
}
203205

204206
val projectModuleRef = getReference(projectID)
Lines changed: 81 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package ch.epfl.scala
22

3-
import java.nio.charset.StandardCharsets
43
import java.nio.file.Paths
54
import java.time.Instant
65

@@ -22,44 +21,35 @@ import sjsonnew.shaded.scalajson.ast.unsafe.JValue
2221
import sjsonnew.support.scalajson.unsafe.{Parser => JsonParser, _}
2322

2423
object SubmitDependencyGraph {
25-
val Submit = "githubSubmitDependencyGraph"
26-
val brief = "Submit the dependency graph to Github Dependency API."
27-
val detail = "Submit the dependency graph of a set of projects and scala versions to Github Dependency API"
28-
val Generate = "generateDependencyGraph"
29-
val briefGenerate = "Generate the dependency graph"
30-
val detailGenerate = "Generate the dependency graph of a set of projects and scala versions"
31-
val commands = new SubmitDependencyGraph(true, Generate, briefGenerate, detailGenerate).commands ++
32-
new SubmitDependencyGraph(false, Submit, brief, detail).commands
33-
}
24+
val Generate = "githubGenerateSnapshot"
25+
private val GenerateUsage = s"""$Generate {"projects":[], "scalaVersions":[]}"""
26+
private val GenerateDetail = "Generate the dependency graph of a set of projects and scala versions"
27+
28+
private val GenerateInternal = s"${Generate}Internal"
29+
private val InternalOnly = "internal usage only"
3430

35-
class SubmitDependencyGraph(
36-
val local: Boolean,
37-
val command: String,
38-
val brief: String,
39-
val detail: String
40-
) {
41-
val usage: String = s"""$command {"projects":[], "scalaVersions":[]}"""
31+
val Submit = "githubSubmitSnapshot"
32+
private val SubmitDetail = "Submit the dependency graph to Github Dependency API."
4233

43-
val internalCommand = s"${command}Internal"
44-
val internalOnly = "internal usage only"
34+
def usage(command: String): String = s"""$command {"projects":[], "scalaVersions":[]}"""
4535

4636
val commands: Seq[Command] = Seq(
47-
Command(command, (usage, brief), detail)(inputParser)(submit),
48-
Command.command(internalCommand, internalOnly, internalOnly)(submitInternal)
37+
Command(Generate, (GenerateUsage, GenerateDetail), GenerateDetail)(inputParser)(generate),
38+
Command.command(GenerateInternal, InternalOnly, InternalOnly)(generateInternal),
39+
Command.command(Submit, SubmitDetail, SubmitDetail)(submit)
4940
)
5041

5142
private lazy val http: HttpClient = Gigahorse.http(Gigahorse.config)
5243

53-
private def inputParser(state: State): Parser[SubmitInput] =
44+
private def inputParser(state: State): Parser[DependencySnapshotInput] =
5445
Parsers.any.*.map { raw =>
5546
JsonParser
5647
.parseFromString(raw.mkString)
57-
.flatMap(Converter.fromJson[SubmitInput])
48+
.flatMap(Converter.fromJson[DependencySnapshotInput])
5849
.get
5950
}.failOnException
6051

61-
private def submit(state: State, input: SubmitInput): State = {
62-
checkGithubEnv() // fail fast if the Github CI environment is incomplete
52+
private def generate(state: State, input: DependencySnapshotInput): State = {
6353
val loadedBuild = state.setting(Keys.loadedBuild)
6454
// all project refs that have a Scala version
6555
val projectRefs = loadedBuild.allProjectRefs
@@ -78,65 +68,69 @@ class SubmitDependencyGraph(
7868
state.log.info(s"Resolving snapshot of $buildFile")
7969

8070
val initState = state
81-
.put(githubSubmitInputKey, input)
71+
.put(githubDependencySnapshotInputKey, input)
8272
.put(githubBuildFile, githubapi.FileInfo(buildFile.toString))
8373
.put(githubManifestsKey, Map.empty[String, Manifest])
8474
.put(githubProjectsKey, projectRefs)
8575

8676
val storeAllManifests = scalaVersions.flatMap { scalaVersion =>
8777
Seq(s"++$scalaVersion", s"Global/${githubStoreDependencyManifests.key} $scalaVersion")
8878
}
89-
val commands = storeAllManifests :+ internalCommand
79+
val commands = storeAllManifests :+ GenerateInternal
9080
commands.toList ::: initState
9181
}
9282

93-
private def submitInternal(state: State): State = {
83+
private def generateInternal(state: State): State = {
9484
val snapshot = githubDependencySnapshot(state)
95-
val snapshotUrl = s"${githubApiUrl()}/repos/${githubRepository()}/dependency-graph/snapshots"
96-
9785
val snapshotJson = CompactPrinter(Converter.toJsonUnsafe(snapshot))
98-
9986
val snapshotJsonFile = IO.withTemporaryFile("dependency-snapshot-", ".json", keepFile = true) { file =>
10087
IO.write(file, snapshotJson)
10188
state.log.info(s"Dependency snapshot written to ${file.getAbsolutePath}")
10289
file
10390
}
91+
setGithubOutputs("snapshot-json-path" -> snapshotJsonFile.getAbsolutePath)
92+
state.put(githubSnapshotFileKey, snapshotJsonFile)
93+
}
10494

105-
if (local) state
106-
else {
107-
108-
val request = Gigahorse
109-
.url(snapshotUrl)
110-
.post(snapshotJson, StandardCharsets.UTF_8)
111-
.addHeaders(
112-
"Content-Type" -> "application/json",
113-
"Authorization" -> s"token ${githubToken()}"
114-
)
115-
116-
state.log.info(s"Submiting dependency snapshot of job ${snapshot.job} to $snapshotUrl")
117-
val result = for {
118-
httpResp <- Try(Await.result(http.processFull(request), Duration.Inf))
119-
snapshot <- getSnapshot(httpResp)
120-
} yield {
121-
state.log.info(s"Submitted successfully as $snapshotUrl/${snapshot.id}")
122-
setGithubOutputs(
123-
"submission-id" -> s"${snapshot.id}",
124-
"submission-api-url" -> s"${snapshotUrl}/${snapshot.id}",
125-
"snapshot-json-path" -> snapshotJsonFile.getAbsolutePath
95+
def submit(state: State): State = {
96+
checkGithubEnv() // fail if the Github CI environment
97+
val snapshotJsonFile = state
98+
.get(githubSnapshotFileKey)
99+
.getOrElse(
100+
throw new MessageOnlyException(
101+
"Missing snapshot file. This command must execute after the githubGenerateSnapshot command"
126102
)
127-
state
128-
}
129-
130-
result.get
103+
)
104+
val snapshotUrl = s"${githubApiUrl()}/repos/${githubRepository()}/dependency-graph/snapshots"
105+
val job = githubJob()
106+
val request = Gigahorse
107+
.url(snapshotUrl)
108+
.post(snapshotJsonFile)
109+
.addHeaders(
110+
"Content-Type" -> "application/json",
111+
"Authorization" -> s"token ${githubToken()}"
112+
)
113+
114+
state.log.info(s"Submitting dependency snapshot of job $job to $snapshotUrl")
115+
val result = for {
116+
httpResp <- Try(Await.result(http.processFull(request), Duration.Inf))
117+
snapshot <- getSnapshot(httpResp)
118+
} yield {
119+
state.log.info(s"Submitted successfully as $snapshotUrl/${snapshot.id}")
120+
setGithubOutputs(
121+
"submission-id" -> s"${snapshot.id}",
122+
"submission-api-url" -> s"${snapshotUrl}/${snapshot.id}"
123+
)
124+
state
131125
}
126+
127+
result.get
132128
}
133129

134130
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter
135-
private def setGithubOutputs(outputs: (String, String)*): Unit = IO.writeLines(
136-
file(githubOutput),
137-
outputs.toSeq.map { case (name, value) => s"${name}=${value}" },
138-
append = true
139-
)
131+
private def setGithubOutputs(outputs: (String, String)*): Unit =
132+
for (output <- githubOutput())
133+
IO.writeLines(output, outputs.map { case (name, value) => s"${name}=${value}" }, append = true)
140134

141135
private def getSnapshot(httpResp: FullResponse): Try[SnapshotResponse] =
142136
httpResp.status match {
@@ -182,32 +176,32 @@ class SubmitDependencyGraph(
182176
}
183177

184178
private def checkGithubEnv(): Unit = {
185-
githubWorkspace()
186-
githubWorkflow()
187-
githubJobName()
188-
githubAction()
189-
githubRunId()
190-
githubSha()
191-
githubRef()
192-
githubApiUrl()
193-
githubRepository()
194-
githubToken()
195-
}
196-
197-
private def githubWorkspace(): String = githubCIEnv("GITHUB_WORKSPACE")
198-
private def githubWorkflow(): String = githubCIEnv("GITHUB_WORKFLOW")
199-
private def githubJobName(): String = githubCIEnv("GITHUB_JOB")
200-
private def githubAction(): String = githubCIEnv("GITHUB_ACTION")
201-
private def githubRunId(): String = githubCIEnv("GITHUB_RUN_ID")
202-
private def githubSha(): String = githubCIEnv("GITHUB_SHA")
203-
private def githubRef(): String = githubCIEnv("GITHUB_REF")
204-
private def githubApiUrl(): String = githubCIEnv("GITHUB_API_URL")
205-
private def githubRepository(): String = githubCIEnv("GITHUB_REPOSITORY")
206-
private def githubToken(): String = githubCIEnv("GITHUB_TOKEN")
207-
private def githubOutput(): String = githubCIEnv("GITHUB_OUTPUT")
208-
209-
private def githubCIEnv(name: String): String =
210-
Properties.envOrNone(name).orElse(Some("").find(_ => local)).getOrElse {
179+
def check(name: String): Unit = Properties.envOrNone(name).orElse {
211180
throw new MessageOnlyException(s"Missing environment variable $name. This task must run in a Github Action.")
212181
}
182+
check("GITHUB_WORKSPACE")
183+
check("GITHUB_WORKFLOW")
184+
check("GITHUB_JOB")
185+
check("GITHUB_ACTION")
186+
check("GITHUB_RUN_ID")
187+
check("GITHUB_SHA")
188+
check("GITHUB_REF")
189+
check("GITHUB_API_URL")
190+
check("GITHUB_REPOSITORY")
191+
check("GITHUB_TOKEN")
192+
check("GITHUB_OUTPUT")
193+
}
194+
195+
private def githubWorkspace(): String = Properties.envOrElse("GITHUB_WORKSPACE", "")
196+
private def githubWorkflow(): String = Properties.envOrElse("GITHUB_WORKFLOW", "")
197+
private def githubJobName(): String = Properties.envOrElse("GITHUB_JOB", "")
198+
private def githubAction(): String = Properties.envOrElse("GITHUB_ACTION", "")
199+
private def githubRunId(): String = Properties.envOrElse("GITHUB_RUN_ID", "")
200+
private def githubSha(): String = Properties.envOrElse("GITHUB_SHA", "")
201+
private def githubRef(): String = Properties.envOrElse("GITHUB_REF", "")
202+
203+
private def githubApiUrl(): String = Properties.envOrElse("GITHUB_API_URL", "")
204+
private def githubRepository(): String = Properties.envOrElse("GITHUB_REPOSITORY", "")
205+
private def githubToken(): String = Properties.envOrElse("GITHUB_TOKEN", "")
206+
private def githubOutput(): Option[File] = Properties.envOrNone("GITHUB_OUTPUT").map(file)
213207
}

sbt-plugin/src/sbt-test/dependency-manifest/ignore-scaladoc/build.sbt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ch.epfl.scala.githubapi.DependencyRelationship
22
import ch.epfl.scala.githubapi.DependencyScope
33
import ch.epfl.scala.githubapi.Manifest
4-
import ch.epfl.scala.SubmitInput
4+
import ch.epfl.scala.DependencySnapshotInput
55
import sjsonnew.shaded.scalajson.ast.unsafe.JString
66

77
val checkScaladoc = taskKey[Unit]("Check scaladoc_3 is in the manifest ")
@@ -17,8 +17,8 @@ inThisBuild(
1717
)
1818

1919
Global / ignoreScaladoc := {
20-
val input = SubmitInput(None, Vector.empty, ignoredConfigs = Vector("scala-doc-tool"))
21-
StateTransform(state => state.put(githubSubmitInputKey, input))
20+
val input = DependencySnapshotInput(None, Vector.empty, ignoredConfigs = Vector("scala-doc-tool"))
21+
StateTransform(state => state.put(githubDependencySnapshotInputKey, input))
2222
}
2323

2424
lazy val p1 = project

sbt-plugin/src/sbt-test/dependency-manifest/ignore-test/build.sbt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ch.epfl.scala.githubapi.DependencyRelationship
22
import ch.epfl.scala.githubapi.DependencyScope
33
import ch.epfl.scala.githubapi.Manifest
4-
import ch.epfl.scala.SubmitInput
4+
import ch.epfl.scala.DependencySnapshotInput
55
import sjsonnew.shaded.scalajson.ast.unsafe.JString
66

77
val checkTest = taskKey[Unit]("Check munit_3 is in the manifest ")
@@ -17,8 +17,8 @@ inThisBuild(
1717
)
1818

1919
Global / ignoreTestConfig := {
20-
val input = SubmitInput(None, Vector.empty, ignoredConfigs = Vector("test"))
21-
StateTransform(state => state.put(githubSubmitInputKey, input))
20+
val input = DependencySnapshotInput(None, Vector.empty, ignoredConfigs = Vector("test"))
21+
StateTransform(state => state.put(githubDependencySnapshotInputKey, input))
2222
}
2323

2424
lazy val p1 = project
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
> 'githubGenerateSnapshot {}'
2+
> Global / checkManifests 4
3+
4+
> 'githubGenerateSnapshot {"ignoredModules":["a_2.13", "b_2.13"]}'
5+
> Global / checkManifests 2
6+
7+
> 'githubGenerateSnapshot {"ignoredModules":["a_2.12", "a_2.13", "b_2.13"]}'
8+
> Global / checkManifests 1
9+
10+
> 'githubGenerateSnapshot {"ignoredModules":[]}'
11+
> Global / checkManifests 4
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-> 'githubGenerateSnapshot {}'
2+
-> 'Global / githubGenerateSnapshot {"onResolveFailure": "error"}'
3+
4+
> 'githubGenerateSnapshot {"onResolveFailure": "warning"}'
5+
> Global / checkManifests 1

sbt-plugin/src/sbt-test/submit-snapshot/ci-submit/test

Lines changed: 0 additions & 12 deletions
This file was deleted.

sbt-plugin/src/sbt-test/submit-snapshot/resolve-failure/test

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)