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

Proposal: Improve branch selection #2281

Merged
merged 29 commits into from
Oct 18, 2021
Merged

Proposal: Improve branch selection #2281

merged 29 commits into from
Oct 18, 2021

Conversation

alejandrohdezma
Copy link
Member

@alejandrohdezma alejandrohdezma commented Oct 13, 2021

What has been done in this PR?

This PR improves the branch selection feature added in #2183 by allowing to be used not only for users of the scala-steward-action or users that run their own instance of Steward, but to anyone using the repos.md feature.

How?

Instead of receiving the default branch to use from the CLI, I've updated the repos.md parser to also allow the following syntax:

- organization/repository:branch

The Repo class has been updated with a new field branch: Option[Branch]. If that field is present, that branch will be used as the default branch instead of actual default branch.

What does this change mean?

This change means that repositories like cats or http4s (or any repository using multibranch) can maintain several branches updated with Scala Steward by updating the repos.md line to:

- http4s/http4s
+ http4s/http4s:main
+ http4s/http4s:0.23.x
+ http4s/http4s:0.22.x
+ http4s/http4s:0.21.x

Isn't this a breaking change?

Removing the CLI param doesn't provoke a breaking change, since a new version hasn't been released since #2183 was merged 😸.

Want to see it in action?

Here you can see this new feature in action. Steward was run with the following parameters:

--do-not-fork --workspace workspace --repos-file repos.md --git-author-email [email protected] --vcs-login scala-steward --git-ask-pass askpass.sh

with repos.md being:

- alejandrohdezma/scala-steward-new-feature-test
- alejandrohdezma/scala-steward-new-feature-test:0.21.x
- alejandrohdezma/scala-steward-new-feature-test:0.22.x

As you can see here Scala Steward created 3 PRs, each pointing to a different branch, and each one of them using the .scala-steward.conf present in that branch.

Signed-off-by: Alejandro Hernández <[email protected]>
Signed-off-by: Alejandro Hernández <[email protected]>
Signed-off-by: Alejandro Hernández <[email protected]>
@codecov
Copy link

codecov bot commented Oct 13, 2021

Codecov Report

Merging #2281 (2cc0c9b) into master (4939946) will decrease coverage by 0.00%.
The diff coverage is 70.37%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2281      +/-   ##
==========================================
- Coverage   77.83%   77.82%   -0.01%     
==========================================
  Files         135      135              
  Lines        2287     2291       +4     
  Branches       51       50       -1     
==========================================
+ Hits         1780     1783       +3     
- Misses        507      508       +1     
Impacted Files Coverage Δ
.../scala/org/scalasteward/core/application/Cli.scala 96.15% <ø> (ø)
...ala/org/scalasteward/core/nurture/NurtureAlg.scala 0.00% <0.00%> (ø)
...org/scalasteward/core/repocache/RepoCacheAlg.scala 0.00% <0.00%> (ø)
...teward/core/vcs/bitbucket/RepositoryResponse.scala 87.50% <33.33%> (-3.81%) ⬇️
...org/scalasteward/core/application/StewardAlg.scala 44.44% <50.00%> (+0.32%) ⬆️
...ala/org/scalasteward/core/application/Config.scala 97.56% <100.00%> (-0.06%) ⬇️
...ain/scala/org/scalasteward/core/edit/EditAlg.scala 60.60% <100.00%> (+1.23%) ⬆️
...main/scala/org/scalasteward/core/git/package.scala 100.00% <100.00%> (ø)
...in/scala/org/scalasteward/core/vcs/VCSApiAlg.scala 100.00% <100.00%> (ø)
...n/scala/org/scalasteward/core/vcs/VCSRepoAlg.scala 76.47% <100.00%> (ø)
... and 4 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4939946...2cc0c9b. Read the comment docs.

@fthomas
Copy link
Member

fthomas commented Oct 13, 2021

I really would like to have this feature in Scala Steward but more changes are needed to properly support multiple branches. (Some of them were in #1469.) For example, for each branch we need to have different RepoCaches that are persisted to disk. I think in this PR, the RepoCaches for each branch is persisted to the same file and thus overwriting the cache of a prior branch.

@alejandrohdezma
Copy link
Member Author

I can try to include the changes in the linked PR

@alejandrohdezma
Copy link
Member Author

Hey @fthomas I've already included all the missing changes in #1469. I believe the cache issue is resolved, given that the cache is created using the Repo as key, and the Repo contains the custom branch (if any is present), but if I'm misinterpreting something, let me know.

The only missing thing would be to try this using fork (I've already tried it using the doNotFork). Do you have any kind of playground for testing this kind of changes? If not, I can set something up quickly.

Once we are happy with the solution, I can update README and documentation, and create a PR for the GitHub Action.

Signed-off-by: Alejandro Hernández <[email protected]>
Signed-off-by: Alejandro Hernández <[email protected]>
@alejandrohdezma
Copy link
Member Author

I've checked with this test repo (using --do-not-fork) and the cache is created succesfully. It creates 3 repo_cache.json files:

  • workspace/store/repo_cache/v1/github/alejandrohdezma/scala-steward-new-feature-test/repo_cache.json
  • workspace/store/repo_cache/v1/github/alejandrohdezma/scala-steward-new-feature-test/0.21.x/repo_cache.json
  • workspace/store/repo_cache/v1/github/alejandrohdezma/scala-steward-new-feature-test/0.22.x/repo_cache.json

@alejandrohdezma
Copy link
Member Author

Also, it seems the KeyDecoder[Repo] is unused. Should I remove it? Or is it there for some reason?

@fthomas
Copy link
Member

fthomas commented Oct 16, 2021

Also, it seems the KeyDecoder[Repo] is unused. Should I remove it? Or is it there for some reason?

It was added in this ancient commit and was required for the Decoder[Store] instance there. It was then later required for the JsonKeyValueStore which lost that requirement in #1220. It looks indeed unused now and can be removed.

@fthomas
Copy link
Member

fthomas commented Oct 16, 2021

The only missing thing would be to try this using fork (I've already tried it using the doNotFork). Do you have any kind of playground for testing this kind of changes? If not, I can set something up quickly.

I could run it locally on https://github.com/scala-steward-org/test-repo-2 if you like. I created a new test-branch in that repo. If you can add some different dependencies to master and test-branch and update the repos.md in this PR, it is easy for me to try it out.

@fthomas
Copy link
Member

fthomas commented Oct 16, 2021

I just tried it locally:

[info] 2021-10-16 16:15:11,582 INFO  ──────────── Steward scala-steward-org/test-repo-2/test-branch ────────────
[info] 2021-10-16 16:15:11,583 INFO  Check cache of scala-steward-org/test-repo-2/test-branch
[info] 2021-10-16 16:15:12,184 INFO  Clone scala-steward/test-repo-2
[info] 2021-10-16 16:15:12,876 ERROR Steward scala-steward-org/test-repo-2/test-branch failed
[info] java.io.IOException: 'git checkout test-branch' exited with code 1

syncFork already checks out a branch. Maybe parent.default_branch just needs to be replaced with repo.branch.getOrElse(parent.default_branch)?

fthomas added a commit that referenced this pull request Oct 16, 2021
fthomas added a commit that referenced this pull request Oct 16, 2021
This adds `Repo.toPath` which has currently the same implementation as
`Repo.show`. `show` is used as representation in log messages while
`toPath` is used as path components.

This allows us in #2281 to use `owner/repo:branch` for `show` and
`owner/repo/branch` for `toPath`.
@fthomas fthomas mentioned this pull request Oct 16, 2021
…ch-selection-to-repos-file

Signed-off-by: Alejandro Hernández <[email protected]>

# Conflicts:
#	modules/core/src/main/scala/org/scalasteward/core/vcs/data/Repo.scala
#	modules/core/src/main/scala/org/scalasteward/core/vcs/package.scala
#	modules/core/src/test/scala/org/scalasteward/core/vcs/data/RepoTest.scala
@fthomas fthomas added the enhancement New feature or request label Oct 16, 2021
@fthomas fthomas linked an issue Oct 16, 2021 that may be closed by this pull request
@fthomas fthomas added this to the 0.12.0 milestone Oct 16, 2021
@fthomas
Copy link
Member

fthomas commented Oct 17, 2021

Maybe parent.default_branch just needs to be replaced with repo.branch.getOrElse(parent.default_branch)?

I'll revert this since parent.default_branch is already the same as repo.branch. I didn't realized that createForkOrGetRepoWithBranch already modified the parent's default_branch.

@alejandrohdezma
Copy link
Member Author

I've added this PR in the scala-steward-action to support this new feature.

@alejandrohdezma
Copy link
Member Author

I noticed this feature didn't take into account users running Scala Steward for a GitHub App. For those users the only option would be to have something in the repo (some kind of file) that lists the branches to update and request that file via API.

The only problem is that the REST API has a rate-limit of 5000 calls per-hour, so I investigated it using the GraphQL API (that allows to query several repos at once) and this is the output:

Screenshot 2021-10-17 at 13 50 55

So to sum up, we could change the way the branch is added, so it is added to the .scala-steward.conf file (instead of adding :branch) to the repos list. And read and parse that file at startup for all repos in the list, reading a new option branches from that file.

What do you think @fthomas?

@alejandrohdezma
Copy link
Member Author

For example this is the output for the first 100 repositories listed in the GitHub repos.md file:

{
  "data": {
    "r1": {
      "object": null
    },
    "r2": {
      "object": null
    },
    "r3": {
      "object": null
    },
    "r4": {
      "object": null
    },
    "r5": {
      "object": null
    },
    "r6": {
      "object": null
    },
    "r7": {
      "object": {
        "text": "updates.includeScala = true\n"
      }
    },
    "r8": {
      "object": null
    },
    "r9": {
      "object": null
    },
    "r10": {
      "object": {
        "text": "updates.ignore = [\n  { groupId = \"com.typesafe\", artifactId = \"ssl-config-core\" },\n\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-actor\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-actor-typed\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-discovery\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-slf4j\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-stream\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-stream-testkit\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-testkit\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-multi-node-testkit\" },\n\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-http\" },\n  { groupId = \"com.typesafe.akka\", artifactId = \"akka-http-core\" },\n\n  { groupId = \"org.scalatest\", artifactId = \"scalatest\" },\n]\n\nupdates.pin = [\n  { groupId = \"org.scalatest\", artifactId = \"scalatest\", version = \"3.1.\" },\n]\n"
      }
    },
    "r11": {
      "object": null
    },
    "r12": {
      "object": null
    },
    "r13": {
      "object": null
    },
    "r14": {
      "object": null
    },
    "r15": {
      "object": null
    },
    "r16": {
      "object": null
    },
    "r17": {
      "object": null
    },
    "r18": {
      "object": {
        "text": "updates.ignore = [ { groupId = \"org.apache.spark\", artifactId = \"spark-sql\" } ]\n"
      }
    },
    "r19": {
      "object": null
    },
    "r20": {
      "object": null
    },
    "r21": {
      "object": null
    },
    "r22": {
      "object": null
    },
    "r23": {
      "object": {
        "text": "updates.ignore = [ { groupId = \"org.apache.spark\", artifactId = \"spark-sql\" } ]\n"
      }
    },
    "r24": {
      "object": null
    },
    "r25": {
      "object": null
    },
    "r26": {
      "object": null
    },
    "r27": {
      "object": null
    },
    "r28": {
      "object": null
    },
    "r29": {
      "object": null
    },
    "r30": {
      "object": null
    },
    "r31": {
      "object": null
    },
    "r32": {
      "object": null
    },
    "r33": {
      "object": null
    },
    "r34": {
      "object": null
    },
    "r35": {
      "object": null
    },
    "r36": {
      "object": null
    },
    "r37": {
      "object": null
    },
    "r38": {
      "object": null
    },
    "r39": {
      "object": null
    },
    "r40": {
      "object": null
    },
    "r41": {
      "object": null
    },
    "r42": {
      "object": null
    },
    "r43": {
      "object": null
    },
    "r44": {
      "object": {
        "text": "updatePullRequests = \"always\"\ncommits.message = \":arrow_up: update ${artifactName} from ${currentVersion} to ${nextVersion}\"\n"
      }
    },
    "r45": {
      "object": null
    },
    "r46": {
      "object": null
    },
    "r47": {
      "object": null
    },
    "r48": {
      "object": null
    },
    "r49": {
      "object": null
    },
    "r50": {
      "object": null
    },
    "r51": {
      "object": null
    },
    "r52": {
      "object": null
    },
    "r53": {
      "object": null
    },
    "r54": {
      "object": null
    },
    "r55": {
      "object": null
    },
    "r56": {
      "object": null
    },
    "r57": {
      "object": null
    },
    "r58": {
      "object": null
    },
    "r59": {
      "object": null
    },
    "r60": {
      "object": null
    },
    "r61": {
      "object": null
    },
    "r62": {
      "object": null
    },
    "r63": {
      "object": null
    },
    "r64": {
      "object": null
    },
    "r65": {
      "object": null
    },
    "r66": {
      "object": null
    },
    "r67": {
      "object": null
    },
    "r68": {
      "object": null
    },
    "r69": {
      "object": null
    },
    "r70": {
      "object": null
    },
    "r71": {
      "object": null
    },
    "r72": {
      "object": null
    },
    "r73": {
      "object": null
    },
    "r74": {
      "object": null
    },
    "r75": {
      "object": null
    },
    "r76": {
      "object": null
    },
    "r77": {
      "object": null
    },
    "r78": {
      "object": null
    },
    "r79": {
      "object": null
    },
    "r80": {
      "object": null
    },
    "r81": {
      "object": null
    },
    "r82": {
      "object": null
    },
    "r83": {
      "object": null
    },
    "r84": {
      "object": null
    },
    "r85": {
      "object": null
    },
    "r86": {
      "object": null
    },
    "r87": {
      "object": null
    },
    "r88": {
      "object": null
    },
    "r89": {
      "object": null
    },
    "r90": {
      "object": null
    },
    "r91": {
      "object": null
    },
    "r92": {
      "object": {
        "text": "updates.pin  = [ { groupId = \"org.typelevel\", artifactId=\"cats-effect\", version = \"2.\" } ]\n"
      }
    },
    "r93": {
      "object": null
    },
    "r94": {
      "object": null
    },
    "r95": {
      "object": null
    },
    "r96": {
      "object": null
    },
    "r97": {
      "object": null
    },
    "r98": {
      "object": null
    },
    "r99": {
      "object": null
    },
    "r100": {
      "object": null
    }
  }
}

We would just need to find something similar for GitLab/BitBucket users. Although given the amount of usage those have for the public Scala Steward, we could just go with doing one call per repository to retrieve the file.

@fthomas
Copy link
Member

fthomas commented Oct 17, 2021

I noticed this feature didn't take into account users running Scala Steward for a GitHub App.

Oh nooo. 😱 That's the curse of having so many features. Can't we just not support branch selection if it used as GitHub App?

@alejandrohdezma
Copy link
Member Author

I noticed this feature didn't take into account users running Scala Steward for a GitHub App.

Oh nooo. 😱 That's the curse of having so many features. Can't we just not support branch selection if it used as GitHub App?

I suppose. Whatever you prefer, I don't mind trying to implement it. The possible benefit if we can make this work would be that nobody would need to send a PR for updating the repos.md for supporting multi-branch, just adding a new field to the .scala-steward.conf.

But if you are happy with not supporting multi-branch for GitHub Apps and continue with the current implementation it's fine by me 😸

@fthomas
Copy link
Member

fthomas commented Oct 17, 2021

The possible benefit if we can make this work would be that nobody would need to send a PR for updating the repos.md for supporting multi-branch, just adding a new field to the .scala-steward.conf.

What I like about the current approach is that no branch is really special. It is possible to get updates for a branch that is not the default branch without configuring anything in the default branch. If branches are configured via .scala-steward.conf, I guess the default branch becomes special because only it can be used to configure the list of branches that should receive updates.

But if you are happy with not supporting multi-branch for GitHub Apps and continue with the current implementation it's fine by me

Great, then let's continue with the current implementation!

Copy link
Member

@fthomas fthomas left a comment

Choose a reason for hiding this comment

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

Outstanding work @alejandrohdezma!

@fthomas
Copy link
Member

fthomas commented Oct 18, 2021

I'd be happy to merge this PR now. @alejandrohdezma is there anything left you want to do before I hit the merge button?

@alejandrohdezma
Copy link
Member Author

Nothing that I can think of :)

@fthomas fthomas merged commit e96e0ce into scala-steward-org:master Oct 18, 2021
@fthomas fthomas mentioned this pull request Oct 18, 2021
@alejandrohdezma alejandrohdezma deleted the move-default-branch-selection-to-repos-file branch October 18, 2021 06:21
@fthomas
Copy link
Member

fthomas commented Oct 19, 2021

This feature works great! Here are two random PRs in the same repo targeting different branches:

@alejandrohdezma
Copy link
Member Author

How is the feature working, since a new version hasn't been published yet?

@fthomas
Copy link
Member

fthomas commented Oct 19, 2021

My public instance tracks master and does not wait for releases. So every new feature is available instantly.

Should we publish a new version for the GH Action soon?

@alejandrohdezma
Copy link
Member Author

Oh, that's nice. Yeah, that would be super :)

I'm adding a PR for supporting the new --default-repo-conf from the GH Action too, so it would be nice to release both features at the same time :)

@fthomas
Copy link
Member

fthomas commented Oct 19, 2021

0.12.0 is now available.

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.

support branch selection
2 participants