Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
ChenCMD committed Jan 6, 2024
1 parent db36fba commit d987f5a
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 24 deletions.
12 changes: 10 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ javaOptions ++= Seq(
"-XX:+UseG1GC"
)

resolvers += Resolver.sonatypeRepo("snapshots")

libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-effect" % "3.4.8",
"org.typelevel" %%% "cats-mtl" % "1.3.0"
"org.typelevel" %%% "cats-effect" % "3.4.8",
"org.typelevel" %%% "cats-mtl" % "1.3.0",
"org.http4s" %%% "http4s-core" % "0.23.23",
"org.http4s" %%% "http4s-client" % "0.23.23",
"org.http4s" %%% "http4s-dsl" % "0.23.23",
"org.http4s" %%% "http4s-circe" % "0.23.23",
"org.http4s" %% "http4s-blaze-client" % "0.23.10",
"io.circe" %%% "circe-generic" % "0.14.6"
)
3 changes: 2 additions & 1 deletion src/main/scala/com/github/chencmd/datapacklinter/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,15 @@ object Main extends IOApp {
}
}

given CIPlatformInteractionInstr[F] = interaction
manageCache <- Resource.eval {
given CIPlatformInteractionInstr[F] = interaction
context match {
case Platform.GitHubActions => GitHubManageCache.createInstr(CACHE_VERSION)
case Platform.Local => LocalManageCache.createInstr().pure[F]
}
}

given CIPlatformReadKeyedConfigInstr[F] = inputReader
cacheRestoration <- Resource.eval {
context match {
case Platform.GitHubActions => GitHubCacheRestoration.createInstr()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,99 @@
package com.github.chencmd.datapacklinter.ciplatform.ghactions

import com.github.chencmd.datapacklinter.ciplatform.CIPlatformCacheRestorationInstr
import com.github.chencmd.datapacklinter.ciplatform.CIPlatformInteractionInstr
import com.github.chencmd.datapacklinter.ciplatform.CIPlatformReadKeyedConfigInstr
import com.github.chencmd.datapacklinter.ciplatform.ghactions.utils.ActionsGitHub
import com.github.chencmd.datapacklinter.generic.EitherTExtra
import com.github.chencmd.datapacklinter.generic.RaiseNec
import com.github.chencmd.datapacklinter.term.RestoreCacheOrSkip

import cats.data.EitherT
import cats.effect.Async
import cats.implicits.*

import scala.scalajs.js

import typings.octokitWebhooksTypes.mod.PullRequestSynchronizeEvent
import typings.octokitWebhooksTypes.mod.PushEvent

import io.circe.generic.auto.*
import org.http4s.*
import org.http4s.blaze.client.BlazeClientBuilder
import org.http4s.circe.*

object GitHubCacheRestoration {
def createInstr[F[_]: Async](): F[CIPlatformCacheRestorationInstr[F]] = for {
ghCtx <- Async[F].delay {
import typings.actionsGithub.mod.context
context
}
def createInstr[F[_]: Async]()(using
ciInteraction: CIPlatformInteractionInstr[F],
inputReader: CIPlatformReadKeyedConfigInstr[F],
R: RaiseNec[F, String]
): F[CIPlatformCacheRestorationInstr[F]] = for {
ghCtx <- ActionsGitHub.getContext()

tokenOrError <- inputReader.readKey[String]("GITHUB_TOKEN")
token <- tokenOrError.fold(R.raise, _.pure[F])

instr = new CIPlatformCacheRestorationInstr[F] {
override def shouldRestoreCache(): F[RestoreCacheOrSkip] = {
import RestoreCacheOrSkip.*
val commitMessages: List[String] = {
Some(ghCtx).filter(_.eventName == "push")
.map(_.payload.asInstanceOf[PushEvent])
.map(_.commits.toList.map(_.message.toLowerCase()))
.orEmpty
}

val program = for {
_ <- EitherTExtra.exitWhenA(commitMessages.exists(_.contains("[regenerate cache]"))) {
commitMessages: List[String] <- EitherT.liftF {
BlazeClientBuilder[F].resource.use { client =>
ghCtx.eventName match {
case "push" => ghCtx.payload.asInstanceOf[PushEvent].commits.toList.map(_.message).pure[F]
case "pull_request" if ghCtx.payload.action == "synchronize" =>
val payload = ghCtx.payload.asInstanceOf[PullRequestSynchronizeEvent]
val repos = payload.repository
val head = payload.pull_request.head

def getPreviousPushCommitHash(): F[Option[String]] = for {
uri <- Uri
.fromString(
s"""|${ghCtx.apiUrl}/repos/${repos.owner}/${repos.name}/actions/runs
|?branch=${head.ref}
|&event=pull_request
|&status=completed
|""".stripMargin
)
.fold(fail => R.raiseOne(fail.message), _.pure[F])
res <- client
.expect(Request[F](Method.GET, uri)) {
case class WorkflowRun(head_sha: String)
case class RepoActionRunsResult(workflow_runs: List[WorkflowRun])
jsonOf[F, RepoActionRunsResult]
}
.handleErrorWith(err => R.raiseOne(err.getMessage()))
} yield res.workflow_runs.get(1).map(_.head_sha)

// TODO support api pagination
def getTwoCommitBetweenCommitMessages(from: String, to: String): F[List[String]] = for {
uri <- Uri
.fromString(s"${ghCtx.apiUrl}/repos/${repos.owner}/${repos.name}/compare/$from..$to?per_page=100")
.fold(fail => R.raiseOne(fail.message), _.pure[F])
res <- client
.expect(Request[F](Method.GET, uri)) {
case class CommitDetail(message: String)
case class Commit(commit: CommitDetail)
case class RepoCompareResult(commits: List[Commit])
jsonOf[F, RepoCompareResult]
}
.handleErrorWith(err => R.raiseOne(err.getMessage()))
} yield res.commits.drop(1).map(_.commit.message)

import scala.scalajs.js.JSConverters.*
import typings.node.nodeColonconsoleMod.global.console.^ as console
for {
prevPushCommitHash <- getPreviousPushCommitHash()
prevHash = prevPushCommitHash.getOrElse(payload.pull_request.base.sha)
_ <- Async[F].delay(console.log(prevHash))
commitMessages <- getTwoCommitBetweenCommitMessages(prevHash, head.sha)
_ <- Async[F].delay(console.log(commitMessages.toJSArray))
} yield commitMessages
case _ => List.empty.pure[F]
}
}
}
_ <- EitherTExtra.exitWhenA(commitMessages.exists(_.toLowerCase().contains("[regenerate cache]"))) {
Skip("The cache is not used because the commit message contains '[regenerate cache]'.")
}
_ <- EitherTExtra.exitWhenA(ghCtx.eventName == "workflow_dispatch") {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.chencmd.datapacklinter.ciplatform.ghactions

import com.github.chencmd.datapacklinter.ciplatform.CIPlatformManageCacheInstr
import com.github.chencmd.datapacklinter.ciplatform.ghactions.utils.ActionsGitHub
import com.github.chencmd.datapacklinter.generic.AsyncExtra
import com.github.chencmd.datapacklinter.generic.RaiseNec
import com.github.chencmd.datapacklinter.utils.Path
Expand All @@ -15,16 +16,15 @@ import typings.actionsCache.mod as cache

object GitHubManageCache {
def createInstr[F[_]: Async](cacheVersion: Int): F[CIPlatformManageCacheInstr[F]] = for {
ghCtx <- Async[F].delay {
import typings.actionsGithub.mod.context
context
}
ghCtx <- ActionsGitHub.getContext()
instr = new CIPlatformManageCacheInstr[F] {
override def store(paths: List[Path]): F[Unit] = AsyncExtra.fromPromise {
cache.saveCache(
paths.map(_.toString).toJSArray,
makeCacheKey(ghCtx.ref, js.Date.now())
).`then`(_ => ())
cache
.saveCache(
paths.map(_.toString).toJSArray,
makeCacheKey(ghCtx.ref, js.Date.now())
)
.`then`(_ => ())
}

override def restore(paths: List[Path])(using R: RaiseNec[F, String]): F[Boolean] = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.github.chencmd.datapacklinter.ciplatform.ghactions.utils

import com.github.chencmd.datapacklinter.generic.AsyncExtra

import cats.effect.kernel.Async
import cats.implicits.*

import scala.scalajs.js

private trait ActionsGitHub extends js.Object {
val context: typings.actionsGithub.libContextMod.Context
}

object ActionsGitHub {
def getContext[F[_]: Async](): F[typings.actionsGithub.libContextMod.Context] = {
AsyncExtra.fromPromise(js.`import`[ActionsGitHub]("@actions/github")).map(_.context)
}
}

0 comments on commit d987f5a

Please sign in to comment.