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

Add dependency dirs for monorepo config #647

Merged
merged 12 commits into from
Sep 26, 2023
22 changes: 22 additions & 0 deletions docs/configuration/basic_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,26 @@ scmVersion {
}
```

Use the `include` configuration parameter within a `monorepos` block to identify dependencies
directories that should be added to consideration when calculating whether to increment
the version of the parent project. For example if we have 2 modules `A` & `B` in our repository,
and we have a composite build of `A` that has a dependency on `B` we can set on `A` a dependency on `B` and get
increment to the version of `A` even if its code did not change, but we only had changes in `B`

Note: these values need to be relative to project root


```
scmVersion {
monorepos {
include([
"common/sdkA",
"common/sdkB"
])
}
}
```

Version calculation rules:
1. Changes to files within a submodule increment that submodule's version only.
2. Changes to a submodule do not cause a change to the parent project's version if
Expand All @@ -138,6 +158,8 @@ the parent is set to ignore that submodule, via `exclude()`.
`exclude()` will cause the parent project's version to increment but not the
versions of any submodules. If this is desired then consider wiring the `createRelease` or
`release` tasks of the submodules to be dependencies of the tasks of the same name in the parent.
4. Changes to directories provided with `include` configuration will also cause an
incrementation of version (even if the main module did not have any changes)

## Releasing

Expand Down
3 changes: 2 additions & 1 deletion docs/examples/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ with these key configuration objects available for reference:

* [RepositoryConfig](https://github.com/allegro/axion-release-plugin/blob/main/src/main/groovy/pl/allegro/tech/build/axion/release/domain/RepositoryConfig.groovy)

* [MonorepoConfig](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/MonorepoConfig.java)
* [
* MonorepoConfig](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/MonorepoConfig.java)

* [NextVersionConfig](https://github.com/allegro/axion-release-plugin/blob/main/src/main/java/pl/allegro/tech/build/axion/release/domain/NextVersionConfig.java)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class DummyRepository implements ScmRepository {
}

@Override
ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders) {
ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders, Set<String> dependenciesFolders) {
return new ScmPosition('', '', 'master')
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class NoOpRepository implements ScmRepository {
}

@Override
ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders) {
ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders, Set<String> dependenciesFolders) {
return delegateRepository.positionOfLastChangeIn(path)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package pl.allegro.tech.build.axion.release.domain;

import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;

import java.util.LinkedList;
import java.util.List;

public abstract class MonorepoConfig extends BaseExtension {
@Input
public abstract ListProperty<String> getProjectDirs();
@Input
public abstract SetProperty<String> getDependenciesDirs();

@Internal
public ListProperty<String> getExcludeDirs() { return getProjectDirs(); }
Expand All @@ -21,4 +23,8 @@ public void exclude(String dir) {
public void exclude(List<String> dirs) {
getProjectDirs().addAll(dirs);
}

public void include(List<String> dirs) {
getDependenciesDirs().addAll(dirs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public VersionResolver(ScmRepository repository, String projectRootRelativePath)

public VersionContext resolveVersion(VersionProperties versionProperties, TagProperties tagProperties, NextVersionProperties nextVersionProperties) {
ScmPosition latestChangePosition = repository.positionOfLastChangeIn(
projectRootRelativePath, versionProperties.getMonorepoConfig().getProjectDirs().get()
projectRootRelativePath, versionProperties.getMonorepoConfig().getProjectDirs().get(), versionProperties.getMonorepoConfig().getDependenciesDirs().get()
);

VersionFactory versionFactory = new VersionFactory(versionProperties, tagProperties, nextVersionProperties, latestChangePosition, repository.isLegacyDefTagnameRepo());
Expand Down Expand Up @@ -102,6 +102,9 @@ private VersionInfo readVersions(
// Now if we test for anywhere from C to E we should get 1.3.0
String tagCommitRevision = currentVersionInfo.commit != null ? currentVersionInfo.commit : "";
onLatestVersion = repository.isIdenticalForPath(projectRootRelativePath, latestChangePosition.getRevision(),tagCommitRevision);
for (String dependency: versionProperties.getMonorepoConfig().getDependenciesDirs().get()) {
onLatestVersion = onLatestVersion && repository.isIdenticalForPath(dependency, latestChangePosition.getRevision(),tagCommitRevision);
}
}

return new VersionInfo(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pl.allegro.tech.build.axion.release.domain.scm;

import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

public interface ScmRepository {
Expand All @@ -19,7 +20,7 @@ public interface ScmRepository {

ScmPosition currentPosition();

ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders);
ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders, Set<String> dependenciesFolders);

Boolean isIdenticalForPath(String path, String latestChangeRevision, String tagCommitRevision);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -250,24 +251,28 @@ public void commit(List<String> patterns, String message) {
}

@Override
public ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders) {
public ScmPosition positionOfLastChangeIn(String path, List<String> excludeSubFolders, Set<String> dependenciesFolders) {
RevCommit lastCommit;

// if the path is empty ('') then it means we are at the root of the Git directory
// in which case, we should exclude changes that occurred in subdirectory projects when deciding on
// which is the latest change that is relevant to the root project
try {
LogCommand logCommand;
if (path.isEmpty()) {
LogCommand logCommand = jgitRepository.log().setMaxCount(1);
logCommand = jgitRepository.log().setMaxCount(1);
for (String excludedPath : excludeSubFolders) {
logCommand.excludePath(asUnixPath(excludedPath));
}
lastCommit = logCommand.call().iterator().next();
} else {
String unixStylePath = asUnixPath(path);
assertPathExists(unixStylePath);
lastCommit = jgitRepository.log().setMaxCount(1).addPath(unixStylePath).call().iterator().next();
logCommand = jgitRepository.log().setMaxCount(1).addPath(unixStylePath);
for (String dep: dependenciesFolders) {
logCommand.addPath(asUnixPath(dep));
}
}
lastCommit = logCommand.call().iterator().next();
} catch (GitAPIException e) {
throw new ScmException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ class GitRepositoryTest extends Specification {
repository.commit([fileInB], 'Add file bar in subdirB')

when:
ScmPosition position = repository.positionOfLastChangeIn('a\\aa', [])
ScmPosition position = repository.positionOfLastChangeIn('a\\aa', [], [].toSet())

then:
position.revision == headSubDirAChanged
Expand Down Expand Up @@ -552,7 +552,32 @@ class GitRepositoryTest extends Specification {
commitFile('after/aa', 'after')

when:
ScmPosition position = repository.positionOfLastChangeIn(importantDir, [])
ScmPosition position = repository.positionOfLastChangeIn(importantDir, [], [].toSet())

then:
position.revision == headSubDirAChanged
}

def "last position with monorepo dependency config - change made in dependency folder"() {
given:
String importantDir = 'a/aa'
String dependencyDir = 'b/bb'
String notInterestingDir = 'c/cc'


commitFile(notInterestingDir, 'unintresting1')
commitFile(notInterestingDir, 'unintresting2')

commitFile(importantDir, 'main_dir')
commitFile(dependencyDir, 'dep_dir')
String headSubDirAChanged = rawRepository.head().id

commitFile(notInterestingDir, 'non_intresting')

commitFile('after/aa', 'after')

when:
ScmPosition position = repository.positionOfLastChangeIn(importantDir, [], [dependencyDir].toSet())

then:
position.revision == headSubDirAChanged
Expand Down