Skip to content

Commit

Permalink
Supports multiple git publications
Browse files Browse the repository at this point in the history
Previously we only supported one git publication per project. Now you
can declare multiple of them if you need to push to multiple branches or
multiple repositories.

Fixes #86
  • Loading branch information
ajoberstar committed Feb 12, 2022
1 parent 3e0159e commit 80da9de
Show file tree
Hide file tree
Showing 5 changed files with 335 additions and 74 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ gitPublish {
}
```

As of v4.1.0, you can now configure multiple publications (e.g. to target different repositories or branches).

```groovy
gitPublish {
commitMessage = 'My favorite commit message' // configures the main publication
publications {
// main
main {
branch = 'great-branch' // alternatively can configure at the top-level of the gitPublish block
// ... any other config from the gitPublish block ...
}
other {
branch = 'some-branch' // may need branch.set('some-branch')
// ... any other config from the gitPublish block ...
}
}
}
```

### Tasks and Execution

Generally, you'll just run `gitPublishPush`, but there is a series of four tasks that happen in order.
Expand All @@ -101,6 +122,10 @@ Generally, you'll just run `gitPublishPush`, but there is a series of four tasks
- `gitPublishCommit` - Commits all changes to the working repo.
- `gitPublishPush` - If changes were committed, pushed them to the `repoUri`.

Each publication gets its own set of tasks, with a general `gitPublishPushAll` if you want to push all publications to their respective repos/branches.

As is common in Gradle, the `main` publication is not indicated in task names (e.g. for `main` `gitPublishCommit` and for `other` `gitPublishOtherCommit`).

### Avoiding Extra Copy

If you are generating a large site, you may want to directly generate it into the working repo to save an extra copy step. You can do this with task dependencies and referring to the `repoDir`.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package org.ajoberstar.gradle.git.publish

import org.ajoberstar.grgit.Grgit
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.gradle.testkit.runner.UnexpectedBuildFailure
import spock.lang.IgnoreIf
import spock.lang.Specification
import spock.lang.TempDir

class MultiPublicationCompatTest extends Specification {
@TempDir File tempDir
File projectDir
File buildFile
Grgit remote1
Grgit remote2

def setup() {
projectDir = new File(tempDir, 'project')
buildFile = projectFile('build.gradle')

def remoteDir = new File(tempDir, 'remote')
remote1 = Grgit.init(dir: remoteDir)

remote1File('master.txt') << 'contents here'
remote1.add(patterns: ['.'])
remote1.commit(message: 'first commit')

// handle different init branches to keep existing tests the same
if (remote1.branch.current().name != 'master') {
remote1.checkout(branch: 'master', createBranch: true)
}

remote1.checkout(branch: 'gh-pages', orphan: true)
remote1.remove(patterns: ['master.txt'])
remote1File('index.md') << '# This Page is Awesome!'
remote1File('1.0.0/index.md') << '# Version 1.0.0 is the Best!'
remote1.add(patterns: ['.'])
remote1.commit(message: 'first pages commit')

remote1.checkout(branch: 'master')

def remote2Dir = new File(tempDir, 'remote2')
remote2 = Grgit.init(dir: remote2Dir)

remote2File('master.txt') << 'contents here'
remote2.add(patterns: ['.'])
remote2.commit(message: 'first commit')

// handle different init branches to keep existing tests the same
if (remote2.branch.current().name != 'master') {
remote2.checkout(branch: 'master', createBranch: true)
}

remote2.checkout(branch: 'gh-pages', orphan: true)
remote2.remove(patterns: ['master.txt'])
remote2File('index.md') << '# This Page is Awesomest!'
remote2File('1.0.0/index.md') << '# Version 1.0.0 is the Best!'
remote2.add(patterns: ['.'])
remote2.commit(message: 'first pages commit')

remote2.checkout(branch: 'master')
}

def 'publish multiple publications'() {
given:
projectFile('src/content.txt') << 'published content here'
projectFile('src2/content.txt') << 'second published content here'

buildFile << """
plugins {
id 'org.ajoberstar.git-publish'
}
gitPublish {
// can configure main at top-level
repoUri = '${remote1.repository.rootDir.toURI()}'
contents.from 'src'
publications {
// can configure main under publication
main {
branch.set('my-pages')
}
second {
repoUri.set('${remote2.repository.rootDir.toURI()}')
branch.set('gh-pages')
contents.from 'src2'
}
}
}
"""
when:
def result = build()
and:
remote1.checkout(branch: 'my-pages')
remote2.checkout(branch: 'gh-pages')
then:
result.task(':gitPublishPush').outcome == TaskOutcome.SUCCESS
remote1.log().size() == 1
remote1File('content.txt').text == 'published content here'
and:
result.task(':gitPublishSecondPush').outcome == TaskOutcome.SUCCESS
remote2.log().size() == 2
remote2File('content.txt').text == 'second published content here'
}

private BuildResult build(String... args = ['gitPublishPushAll', '--stacktrace', '--info', '--configuration-cache']) {
return runner(args).build()
}

private BuildResult buildAndFail(String... args = ['gitPublishPushAll', '--stacktrace', '--info', '--configuration-cache']) {
return runner(args).buildAndFail()
}

private GradleRunner runner(String... args) {
return GradleRunner.create()
.withGradleVersion(System.properties['compat.gradle.version'])
.withPluginClasspath()
.withProjectDir(projectDir)
.forwardOutput()
.withArguments(args)
}

private File remote1File(String path) {
File file = new File(remote1.repository.rootDir, path)
file.parentFile.mkdirs()
return file
}

private File remote2File(String path) {
File file = new File(remote2.repository.rootDir, path)
file.parentFile.mkdirs()
return file
}

private File projectFile(String path) {
File file = new File(projectDir, path)
file.parentFile.mkdirs()
return file
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package org.ajoberstar.gradle.git.publish;

import org.gradle.api.Action;
import org.gradle.api.Named;
import org.gradle.api.Project;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.util.PatternFilterable;
import org.gradle.api.tasks.util.PatternSet;

public class GitPublication implements Named {
private final String name;
private final DirectoryProperty repoDir;
private final Property<String> repoUri;
private final Property<String> referenceRepoUri;
private final Property<String> branch;
private final Property<String> commitMessage;
private final Property<Boolean> sign;
private final CopySpec contents;
private final PatternFilterable preserve;

public GitPublication(String name, Project project, ObjectFactory objectFactory) {
this.name = name;
this.repoDir = objectFactory.directoryProperty();
this.repoUri = objectFactory.property(String.class);
this.referenceRepoUri = objectFactory.property(String.class);
this.branch = objectFactory.property(String.class);
this.commitMessage = objectFactory.property(String.class);
this.sign = objectFactory.property(Boolean.class);

this.contents = project.copySpec();
this.preserve = new PatternSet();
this.preserve.include(".git/**/*");
}

@Override
public String getName() {
return name;
}

public DirectoryProperty getRepoDir() {
return repoDir;
}

public Property<String> getRepoUri() {
return repoUri;
}

public Property<String> getReferenceRepoUri() {
return referenceRepoUri;
}

public Property<String> getBranch() {
return branch;
}

public Property<String> getCommitMessage() {
return commitMessage;
}

public Property<Boolean> getSign() {
return sign;
}

public CopySpec getContents() {
return contents;
}

public void contents(Action<? super CopySpec> action) {
action.execute(contents);
}

public PatternFilterable getPreserve() {
return preserve;
}

public void preserve(Action<? super PatternFilterable> action) {
action.execute(preserve);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,75 +3,67 @@
import javax.inject.Inject;

import org.gradle.api.Action;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Project;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.util.PatternFilterable;
import org.gradle.api.tasks.util.PatternSet;

public class GitPublishExtension {
private final DirectoryProperty repoDir;
private final Property<String> repoUri;
private final Property<String> referenceRepoUri;
private final Property<String> branch;
private final Property<String> commitMessage;
private final Property<Boolean> sign;
private final CopySpec contents;
private final PatternFilterable preserve;
private final NamedDomainObjectContainer<GitPublication> publications;

@Inject
public GitPublishExtension(Project project, ObjectFactory objectFactory) {
this.repoDir = objectFactory.directoryProperty();
this.repoUri = objectFactory.property(String.class);
this.referenceRepoUri = objectFactory.property(String.class);
this.branch = objectFactory.property(String.class);
this.commitMessage = objectFactory.property(String.class);
this.sign = objectFactory.property(Boolean.class);

this.contents = project.copySpec();
this.preserve = new PatternSet();
this.preserve.include(".git/**/*");
this.publications = objectFactory.domainObjectContainer(GitPublication.class, name -> new GitPublication(name, project, objectFactory));
}

public NamedDomainObjectContainer<GitPublication> getPublications() {
return publications;
}

public void publications(Action<? super NamedDomainObjectContainer<? super GitPublication>> action) {
action.execute(publications);
}

public DirectoryProperty getRepoDir() {
return repoDir;
return publications.getByName("main").getRepoDir();
}

public Property<String> getRepoUri() {
return repoUri;
return publications.getByName("main").getRepoUri();
}

public Property<String> getReferenceRepoUri() {
return referenceRepoUri;
return publications.getByName("main").getReferenceRepoUri();
}

public Property<String> getBranch() {
return branch;
return publications.getByName("main").getBranch();
}

public Property<String> getCommitMessage() {
return commitMessage;
return publications.getByName("main").getCommitMessage();
}

public Property<Boolean> getSign() {
return sign;
return publications.getByName("main").getSign();
}

public CopySpec getContents() {
return contents;
return publications.getByName("main").getContents();
}

public void contents(Action<? super CopySpec> action) {
action.execute(contents);
publications.getByName("main").contents(action);
}

public PatternFilterable getPreserve() {
return preserve;
return publications.getByName("main").getPreserve();
}

public void preserve(Action<? super PatternFilterable> action) {
action.execute(preserve);
publications.getByName("main").preserve(action);
}
}
Loading

0 comments on commit 80da9de

Please sign in to comment.