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

Set published-version github output after 'publish' task #847

Merged
merged 3 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions docs/configuration/basic_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,18 +180,7 @@ Version calculation rules:

### GitHub workflow context

If `release` task is executed in GitHub workflow it will generate an output variable `released-version`
that you can access later on in your workflow steps.

```
jobs:
build:
runs-on: ubuntu-latest
steps:
- id: release
run: ./gradlew release
- run: echo ${{steps.release.outputs.released-version}}
```
See [GitHub outputs](ci_servers.md#github-outputs)

## Accessing previous version

Expand Down
45 changes: 41 additions & 4 deletions docs/configuration/ci_servers.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,47 @@ This behavior is experimental and has been tested on the following CI servers:

`axion-release` has dedicated support for GitHub Actions and you don't need any custom configs to make it working.

Here's what Axion does for you under the hood:

- gets the original branch name for workflows triggered by `pull_request` -
see [versionWithBranch](version.md#versionwithbranch-default)
### GitHub outputs

To make it easier for you to chain jobs in a workflow, `axion-release` will provide some information as GitHub outputs.

| name | description |
|---------------------|---------------------------------------------|
| `released-version` | Provided after executing the `release` task |
| `published-version` | Provided after executing the `publish` task |

#### Multi-version builds

If all your Gradle modules use the same version, the output will be a single value, such as:
```
1.0.0
```

However, if each module has its own version, the output will be in JSON format, for example:
```json
{"root-project":"1.0.0","sub-project-1":"2.0.0","sub-project-2":"3.0.0"}
```
where `root-project`, `sub-project-1` and `sub-project-2` are project names from Gradle.

#### Example

```yaml
jobs:
build:
steps:
- id: release
run: ./gradlew release

# for single-version builds
- run: |
echo ${{ steps.release.outputs.released-version }}

# for multi-version builds
- run: |
echo ${{ fromJson(steps.release.outputs.released-version).root-project }}
echo ${{ fromJson(steps.release.outputs.released-version).sub-project-1 }}
echo ${{ fromJson(steps.release.outputs.released-version).sub-project-2 }}
```

## Jenkins

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,34 @@ class BaseIntegrationTest extends RepositoryBasedTest {
}

void buildFile(String contents) {
new FileTreeBuilder(temporaryFolder).file("build.gradle", """
plugins {
id 'pl.allegro.tech.build.axion-release'
}

""" + contents +
new FileTreeBuilder(temporaryFolder).file("build.gradle",
"""
plugins {
id 'pl.allegro.tech.build.axion-release'
}

project.version = scmVersion.version
scmVersion.ignoreGlobalGitConfig = true
""")
$contents

project.version = scmVersion.version
scmVersion.ignoreGlobalGitConfig = true
"""
)
}

void vanillaBuildFile(String contents) {
new FileTreeBuilder(temporaryFolder).file("build.gradle", contents)
}

void vanillaSubprojectBuildFile(String subprojectName, String contents) {
new FileTreeBuilder(temporaryFolder).dir(subprojectName) {
file("build.gradle", contents)
}
}

void vanillaSettingsFile(String contents) {
new FileTreeBuilder(temporaryFolder).file("settings.gradle", contents)
}

GradleRunner gradle() {
return GradleRunner.create()
.withProjectDir(temporaryFolder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,122 @@ class SimpleIntegrationTest extends BaseIntegrationTest {
result.task(":currentVersion").outcome == TaskOutcome.SUCCESS
}

def "should define a github output when running release task in github workflow context"() {
def "should set released-version github output after release task"(String task,
String rootProjectVersion,
String subprojectVersion,
String output) {
given:
def outputFile = File.createTempFile("github-outputs", ".tmp")
environmentVariablesRule.set("GITHUB_ACTIONS", "true")
environmentVariablesRule.set("GITHUB_OUTPUT", outputFile.getAbsolutePath())

buildFile('')
vanillaSettingsFile("""
rootProject.name = 'root-project'

include 'sub-project'
"""
)

vanillaBuildFile("""
plugins {
id 'pl.allegro.tech.build.axion-release'
}

scmVersion {
tag {
prefix = 'root-project-'
}
}
"""
)

vanillaSubprojectBuildFile("sub-project", """
plugins {
id 'pl.allegro.tech.build.axion-release'
}

scmVersion {
tag {
prefix = 'sub-project-'
}
}
"""
)

repository.tag("root-project-$rootProjectVersion")
repository.tag("sub-project-$subprojectVersion")
repository.commit(['.'], 'Some commit')

when:
runGradle('release', '-Prelease.version=1.0.0', '-Prelease.localOnly', '-Prelease.disableChecks')
runGradle(task, '-Prelease.localOnly', '-Prelease.disableChecks')

then:
def definedEnvVariables = outputFile.getText().lines().collect(toList())
definedEnvVariables.contains('released-version=1.0.0')
definedEnvVariables.contains(output)

cleanup:
environmentVariablesRule.clear("GITHUB_ACTIONS", "GITHUB_OUTPUT")

where:
task | rootProjectVersion | subprojectVersion || output
'release' | "1.0.0" | "1.0.0" || 'released-version=1.0.1'
'release' | "1.0.0" | "2.0.0" || 'released-version={"root-project":"1.0.1","sub-project":"2.0.1"}'
':release' | "1.0.0" | "2.0.0" || 'released-version=1.0.1'
':sub-project:release' | "1.0.0" | "2.0.0" || 'released-version=2.0.1'
}

def "should set published-version github output after publish task"(String task,
String rootProjectVersion,
String subprojectVersion,
String output) {
given:
def outputFile = File.createTempFile("github-outputs", ".tmp")
environmentVariablesRule.set("GITHUB_ACTIONS", "true")
environmentVariablesRule.set("GITHUB_OUTPUT", outputFile.getAbsolutePath())

vanillaSettingsFile("""
rootProject.name = 'root-project'

include 'sub-project'
"""
)

vanillaBuildFile("""
plugins {
id 'pl.allegro.tech.build.axion-release'
id 'maven-publish'
}

version = '$rootProjectVersion'
"""
)

vanillaSubprojectBuildFile("sub-project", """
plugins {
id 'pl.allegro.tech.build.axion-release'
id 'maven-publish'
}

version = '$subprojectVersion'
"""
)

when:
runGradle(task)

then:
def definedEnvVariables = outputFile.getText().lines().collect(toList())
definedEnvVariables.contains(output)

cleanup:
environmentVariablesRule.clear("GITHUB_ACTIONS", "GITHUB_OUTPUT")

where:
task | rootProjectVersion | subprojectVersion || output
'publish' | "1.0.0" | "1.0.0" || 'published-version=1.0.0'
'publish' | "1.0.0" | "2.0.0" || 'published-version={"root-project":"1.0.0","sub-project":"2.0.0"}'
':publish' | "1.0.0" | "2.0.0" || 'published-version=1.0.0'
':sub-project:publish' | "1.0.0" | "2.0.0" || 'published-version=2.0.0'
}

def "should return released version on calling cV on repo with release commit"() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package pl.allegro.tech.build.axion.release

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import pl.allegro.tech.build.axion.release.domain.SnapshotDependenciesChecker
import pl.allegro.tech.build.axion.release.domain.VersionConfig
import pl.allegro.tech.build.axion.release.infrastructure.di.VersionResolutionContext
import pl.allegro.tech.build.axion.release.infrastructure.github.GithubService
import pl.allegro.tech.build.axion.release.util.FileLoader

abstract class ReleasePlugin implements Plugin<Project> {
Expand All @@ -21,7 +23,10 @@ abstract class ReleasePlugin implements Plugin<Project> {
void apply(Project project) {
FileLoader.setRoot(project.rootDir)

def versionConfig = project.extensions.create(VERSION_EXTENSION, VersionConfig, project.rootProject.layout.projectDirectory)
Provider<GithubService> githubService = project.gradle.sharedServices
.registerIfAbsent("github", GithubService) {}

VersionConfig versionConfig = project.extensions.create(VERSION_EXTENSION, VersionConfig, project.rootProject.layout.projectDirectory)

project.tasks.withType(BaseAxionTask).configureEach({
it.versionConfig = versionConfig
Expand All @@ -42,6 +47,8 @@ abstract class ReleasePlugin implements Plugin<Project> {
group = 'Release'
description = 'Performs release - creates tag and pushes it to remote.'
dependsOn(VERIFY_RELEASE_TASK)
it.projectName = project.name
it.githubService = githubService
}

project.tasks.register(CREATE_RELEASE_TASK, CreateReleaseTask) {
Expand All @@ -65,9 +72,25 @@ abstract class ReleasePlugin implements Plugin<Project> {
description = 'Prints current project version extracted from SCM.'
}

setGithubOutputsAfterPublishTask(project, githubService)

maybeDisableReleaseTasks(project, versionConfig)
}

private static setGithubOutputsAfterPublishTask(Project project, Provider<GithubService> githubService) {
String projectName = project.name
Provider<String> projectVersion = project.provider { project.version.toString() }

project.plugins.withId('maven-publish') {
project.tasks.named('publish') { task ->
task.usesService(githubService)
task.doLast {
githubService.get().setOutput('published-version', projectName, projectVersion.get())
}
}
}
}

private static void maybeDisableReleaseTasks(Project project, VersionConfig versionConfig) {
project.afterEvaluate {
def context = VersionResolutionContext.create(versionConfig, project.layout.projectDirectory)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package pl.allegro.tech.build.axion.release

import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import pl.allegro.tech.build.axion.release.domain.Releaser
import pl.allegro.tech.build.axion.release.domain.scm.ScmPushResult
import pl.allegro.tech.build.axion.release.domain.scm.ScmPushResultOutcome
import pl.allegro.tech.build.axion.release.infrastructure.di.VersionResolutionContext

import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardOpenOption
import pl.allegro.tech.build.axion.release.infrastructure.github.GithubService

abstract class ReleaseTask extends BaseAxionTask {

@Input
abstract Property<String> getProjectName()

@Internal
abstract Property<GithubService> getGithubService()

@TaskAction
void release() {
VersionResolutionContext context = resolutionContext()
Expand All @@ -28,13 +34,8 @@ abstract class ReleaseTask extends BaseAxionTask {
}

if (result.outcome === ScmPushResultOutcome.SUCCESS) {
if (System.getenv().containsKey('GITHUB_ACTIONS')) {
Files.write(
Paths.get(System.getenv('GITHUB_OUTPUT')),
"released-version=${versionConfig.uncached.decoratedVersion}\n".getBytes(),
StandardOpenOption.APPEND
)
}
String version = versionConfig.uncached.decoratedVersion
githubService.get().setOutput("released-version", projectName.get(), version)
}
}
}
Loading