diff --git a/src/main/scala/kevinlee/github/GitHubApi.scala b/src/main/scala/kevinlee/github/GitHubApi.scala new file mode 100644 index 0000000..54c8cea --- /dev/null +++ b/src/main/scala/kevinlee/github/GitHubApi.scala @@ -0,0 +1,53 @@ +package kevinlee.github + +import cats.Monad +import cats.syntax.all._ +import io.circe._ +import kevinlee.github.data._ +import kevinlee.http.{HttpClient, HttpRequest} + +/** @author Kevin Lee + * @since 2021-01-14 + */ +trait GitHubApi[F[_]] { + def createRelease( + params: GitHubRelease.RequestParams, + repo: GitHubRepoWithAuth, + ): F[Either[GitHubError, Option[GitHubRelease.Response]]] +} + +object GitHubApi { + + def apply[F[_]: Monad](httpClient: HttpClient[F]): GitHubApi[F] = new GitHubApiF[F](httpClient) + + final class GitHubApiF[F[_]: Monad](val httpClient: HttpClient[F]) extends GitHubApi[F] { + // TODO: make it configurable + val baseUrl: String = "https://api.github.com" + + val DefaultAccept: String = "application/vnd.github.v3+json" + + override def createRelease( + params: GitHubRelease.RequestParams, + repo: GitHubRepoWithAuth, + ): F[Either[GitHubError, Option[GitHubRelease.Response]]] = { + val url = s"$baseUrl/repos/${repo.gitHubRepo.org.org}/${repo.gitHubRepo.repo.repo}/releases" + val body = Encoder[GitHubRelease.RequestParams].apply(params) + val httpRequest = HttpRequest.withHeadersAndBody( + HttpRequest.Method.post, + HttpRequest.Uri(url), + HttpRequest.Header("accept" -> DefaultAccept) :: + repo + .accessToken + .toHeaderList, + body, + ) + httpClient + .request[Option[GitHubRelease.Response]](httpRequest) + .map( + _.leftMap(GitHubError.fromHttpError) + .flatMap(res => res.asRight[GitHubError]) + ) + } + } + +} diff --git a/src/main/scala/kevinlee/github/data/github.scala b/src/main/scala/kevinlee/github/data/github.scala index dbc3ba8..510a85b 100644 --- a/src/main/scala/kevinlee/github/data/github.scala +++ b/src/main/scala/kevinlee/github/data/github.scala @@ -4,6 +4,7 @@ import io.estatico.newtype.macros.newtype import java.io.File import kevinlee.git.Git.TagName +import kevinlee.http.HttpRequest import org.kohsuke.github.GHRelease /** @author Kevin Lee @@ -62,4 +63,15 @@ object GitHubRepoWithAuth { override val toString: String = "***Protected***" } + implicit final class AccessTokenOps(val maybeAccessToken: Option[AccessToken]) extends AnyVal { + def toHeaderList: List[HttpRequest.Header] = + maybeAccessToken + .toList + .map(token => + HttpRequest.Header( + "Authorization" -> s"token ${token.accessToken}" + ) + ) + } + }