Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collect HTTP Headers from Coursier for authentication #2533

Merged
merged 1 commit into from
Aug 11, 2022

Conversation

markvandertol
Copy link
Contributor

This PR lets Scala Steward also pick up custom headers used for authentication. This is for example needed for Gitlab. I think looking at csrConfiguration.value.authenticationByRepositoryId is the cleanest and most generic way to achieve this.

Example snippet of a .sbt file from a project that sets a custom HTTP-header for authentication with Coursier:

resolvers += "gitlab-repo" at "https://gitlab.example.com/api/v4/groups/1/-/packages/maven",
csrConfiguration ~= _.addRepositoryAuthentication("gitlab-repo", Authentication(Seq( ("private-token", "xxx") )))

It works for SBT and Mill, but doesn't work for Maven

@codecov
Copy link

codecov bot commented Feb 21, 2022

Codecov Report

Merging #2533 (ffd36e5) into main (fcd5ea3) will decrease coverage by 0.67%.
The diff coverage is 34.09%.

@@            Coverage Diff             @@
##             main    #2533      +/-   ##
==========================================
- Coverage   81.32%   80.65%   -0.68%     
==========================================
  Files         146      146              
  Lines        2592     2621      +29     
  Branches       43       45       +2     
==========================================
+ Hits         2108     2114       +6     
- Misses        484      507      +23     
Impacted Files Coverage Δ
.../scala/org/scalasteward/core/application/Cli.scala 100.00% <ø> (ø)
...a/org/scalasteward/mill/plugin/StewardPlugin.scala 0.00% <0.00%> (ø)
...la/org/scalasteward/sbt/plugin/StewardPlugin.scala 0.00% <0.00%> (ø)
...a/org/scalasteward/core/coursier/CoursierAlg.scala 71.11% <35.71%> (-14.19%) ⬇️
.../org/scalasteward/core/buildtool/mill/parser.scala 66.66% <50.00%> (-1.52%) ⬇️
...org/scalasteward/core/buildtool/maven/parser.scala 100.00% <100.00%> (ø)
...in/scala/org/scalasteward/core/data/Resolver.scala 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Copy link
Contributor

@julienrf julienrf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a couple of minor details that could be discussed (e.g., the usage of Option[List[Header]] vs List[Header], and the way headers are serialized in JSON — I would just write ["foo", "bar"] instead of { "key": "foo", "value": "bar" }), but overall it looks correct to me, and it would unblock all the people that use a gitlab package registry!

@markvandertol
Copy link
Contributor Author

Thanks for having a look. I replaced the Option[List[Header]] with List[Header]. That indeed simplifies the code.
I feel that encoding { "key": "foo", "value": "bar" } as object instead of array is clearer, the same as the credentials object is encoded as { "user": "foo", "pass", "bar" }. Also, because you could have more than one header. If you want I can change this.

@julienrf
Copy link
Contributor

May I kindly request a review from the maintainers?

} else {
Some(
new Authentication(
credentials.fold("")(_.user),
Copy link
Contributor

@exoego exoego Mar 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q) Does "" for user works ?

If not, error message like "Authentication error: missing user name" might help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@exoego exoego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Great job!!

I will wait other maintainers for a week.

@cipriansofronia
Copy link

@markvandertol, could u also update the gitlab docs on how we can use this new feature?

@markvandertol
Copy link
Contributor Author

markvandertol commented Apr 3, 2022

@markvandertol, could u also update the gitlab docs on how we can use this new feature?

@cipriansofronia I've added a few lines explaining how to authenticate against a Gitlab repository. Does this clarify enough how it works? No specific code for Scala Steward is needed.

docs/running.md Outdated
Comment on lines 263 to 264
Scala Steward is compatible with Coursier authentication using headers. To authenticate
using the [Gitlab CI/CD job token](https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html), while also supporting your own private token when performing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@jchapuis
Copy link

jchapuis commented Apr 5, 2022

Looking forward to this one being released, thanks a lot @markvandertol

@cipriansofronia
Copy link

@fthomas can this PR get some ❤️ from you? 😇

@markvandertol
Copy link
Contributor Author

Is there anything preventing this PR from being merged? 🙂

@exoego
Copy link
Contributor

exoego commented Apr 15, 2022

@fthomas Do you have a time to test this with your test Steward instance ??

csrConfiguration.value.authenticationByRepositoryId.toList
if repositoryId == name
(headerKey, headerValue) <- authentication.headers
} yield Resolver.Header(headerKey, headerValue)
Copy link
Contributor

@987Nabil 987Nabil Apr 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should not only take the headers from the csrConfiguration but also username and password.
Setting these via csrConfiguration is not wrong. And I would prefer csrConfiguration over credentials if present, since it is more specific/explicit.

Funny enough, I did not see this pr and coded it myself that way. Maybe you can have a look :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot the @markvandertol :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am going to merge as-is since markvandertol seems busy now.
@987Nabil You can submit a PR for that change 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not replying to this earlier. It indeed looks more consistent, but I'm not entirely sure how large of a breaking change would be, e.g. for people who disabled coursier in their projects. Retrieving the credentials old way, but looking for headers in csrConfiguration shouldn't be breaking, so I propose to do that in a different PR so the impact can better be assessed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do this in another PR for sure. But I think, deactivating coursier and then relying on csrConfiguration where csr = coursier and the description in sbt also explicitly mentions coursier, seems to be odd.

@jchapuis
Copy link

jchapuis commented May 9, 2022

👋 is there anything holding up the merge at this point?

@kaffepanna
Copy link

wave is there anything holding up the merge at this point?

I am wondering that to. This would really be a good thing to have when managing dependencies in private gilab repos

@987Nabil
Copy link
Contributor

wave is there anything holding up the merge at this point?

I am wondering that to. This would really be a good thing to have when managing dependencies in private gilab repos

It is not only gitlb. Also Google Cloud Storage or Artifactregistry or managing packages in AWS need this feature.

@exoego exoego added the enhancement New feature or request label Jun 15, 2022
@exoego
Copy link
Contributor

exoego commented Jun 15, 2022

@markvandertol Sorry for waiting so long. Could you resolve the conflict? 🙇

@markvandertol
Copy link
Contributor Author

No worries. I resolved the merge conflict. 🙂

@michaltomanski
Copy link

Thanks Mark for this PR! It looks promising.

Any chance to have it merged some time soon?

@fthomas
Copy link
Member

fthomas commented Jul 14, 2022

Thanks for having a look. I replaced the Option[List[Header]] with List[Header]. That indeed simplifies the code.

Having the fields optional allows to read in persisted RepoCaches of previous Scala Steward runs. If the header fields are non-optional, Scala Steward fails to read these files:

[info] 2022-07-14 14:48:58,983 INFO  ──────────── Steward scala-steward-org/scala-steward ────────────
[info] 2022-07-14 14:48:58,983 INFO  Check cache of scala-steward-org/scala-steward
[info] 2022-07-14 14:48:59,080 ERROR Failed to parse or decode JSON from /home/frank/data/code/scala-steward/core/workspace/store/repo_cache/v1/github/scala-steward-org/scala-steward/repo_cache.json
[info] io.circe.DecodingFailure$$anon$2: Attempt to decode value on failed cursor: DownField(headers),DownField(MavenRepository),DownArray,DownField(resolvers),DownArray,DownField(dependencyInfos)

Another alternative would be to bump the version of the repoCacheStore here. But for this small change I would prefer making the fields optional.

Other than that, this PR looks good to me.

@markvandertol
Copy link
Contributor Author

Thanks @fthomas for having a look at the PR.

I fixed the issue by using a default value of Nil for the headers, and using deriveConfiguredCodec as shown below.

  @annotation.nowarn("cat=unused-locals")
  implicit val resolverCodec: Codec[Resolver] = {
    implicit val customConfig: Configuration = Configuration.default.withDefaults
    deriveConfiguredCodec
  }

I had to suppress the warning, as the implicit is only used by a macro. I could also have used the compiler flag -Ywarn-macros:after, but that would be inconsistent with other @annotation.nowarn usages.

@exoego exoego added this to the 0.16.0 milestone Aug 11, 2022
@exoego
Copy link
Contributor

exoego commented Aug 11, 2022

Sorry for the late response.

@exoego exoego merged commit 9df61a1 into scala-steward-org:main Aug 11, 2022
@jchapuis
Copy link

jchapuis commented Oct 7, 2022

Any chance this can get shipped in a new release? 😃 🙏 thanks!

@fthomas
Copy link
Member

fthomas commented Dec 21, 2022

Just noticed that this change broke StewardPlugin.scala for old sbt versions. See #2847 for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants