Skip to content

Commit

Permalink
#566: Set custom environment for workflow jobs (#576)
Browse files Browse the repository at this point in the history
* Update error code crawler version

* #566: Add config option for environment

* Remove unused constant

* #566: Set custom environment for workflow jobs

* #566 Add unit tests

* Update dependencies

* Reduce permissions for GitHub workflows

* Update dependencies in test

* Reduce GitHub workflow permissions

* Update changelog

* Fix windows build
  • Loading branch information
kaklakariada authored May 13, 2024
1 parent 5bf476a commit 7bc1ed1
Show file tree
Hide file tree
Showing 31 changed files with 416 additions and 66 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/broken_links_checker.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion .github/workflows/ci-build.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions .github/workflows/test_linux_build_on_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
jobs:
build-on-linux:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
shell: "bash"
Expand All @@ -24,9 +26,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: |
11
17
java-version: 17
cache: "maven"
- name: Set up Go
uses: actions/setup-go@v5
Expand Down Expand Up @@ -64,8 +64,11 @@ jobs:
name: project-keeper-jar
path: artifact
retention-days: 1

run-on-windows:
runs-on: windows-latest
permissions:
contents: read
needs: build-on-linux
steps:
- name: Checkout the repository
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/test_on_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
jobs:
test:
runs-on: windows-latest
permissions:
contents: read
defaults:
run:
shell: "bash"
Expand All @@ -24,6 +26,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: "temurin"
# Java 11 required for test project "my-test-project"
java-version: |
11
17
Expand Down
22 changes: 20 additions & 2 deletions doc/changes/changes_4.3.1.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Project Keeper 4.3.1, released 2024-05-??
# Project Keeper 4.3.1, released 2024-05-13

Code name: Fix CVE-2024-31573 in `org.xmlunit:xmlunit-core:jar:2.9.1:test`
Code name: Environment for GitHub workflow `ci-build.yml`

## Summary

Expand All @@ -10,15 +10,29 @@ This release fixes vulnerability CVE-2024-31573 in `org.xmlunit:xmlunit-core:jar

* #570: Fixed CVE-2024-31573 in `org.xmlunit:xmlunit-core:jar:2.9.1:test`

## Features

* #566: Allowed specifying an environment for GitHub workflow `ci-build.yml`

## Bugfixes

* #571: Fixed failing version increment during dependency update
* #567: Increased timeout for installing go-licenses

## Dependency Updates

### Project Keeper Root Project

#### Plugin Dependency Updates

* Updated `com.exasol:error-code-crawler-maven-plugin:2.0.1` to `2.0.3`

### Project Keeper Shared Model Classes

#### Test Dependency Updates

* Updated `org.mockito:mockito-core:5.11.0` to `5.12.0`

#### Plugin Dependency Updates

* Updated `com.exasol:error-code-crawler-maven-plugin:2.0.2` to `2.0.3`
Expand All @@ -40,6 +54,7 @@ This release fixes vulnerability CVE-2024-31573 in `org.xmlunit:xmlunit-core:jar
#### Test Dependency Updates

* Updated `com.exasol:project-keeper-shared-test-setup:4.3.0` to `4.3.1`
* Updated `org.mockito:mockito-junit-jupiter:5.11.0` to `5.12.0`
* Updated `org.xmlunit:xmlunit-matchers:2.9.1` to `2.10.0`

#### Plugin Dependency Updates
Expand Down Expand Up @@ -77,6 +92,7 @@ This release fixes vulnerability CVE-2024-31573 in `org.xmlunit:xmlunit-core:jar
#### Test Dependency Updates

* Updated `org.jacoco:org.jacoco.agent:0.8.11` to `0.8.12`
* Updated `org.mockito:mockito-core:5.11.0` to `5.12.0`
* Updated `org.xmlunit:xmlunit-matchers:2.9.1` to `2.10.0`

#### Plugin Dependency Updates
Expand All @@ -95,6 +111,8 @@ This release fixes vulnerability CVE-2024-31573 in `org.xmlunit:xmlunit-core:jar
#### Test Dependency Updates

* Updated `org.jacoco:org.jacoco.agent:0.8.11` to `0.8.12`
* Updated `org.mockito:mockito-core:5.11.0` to `5.12.0`
* Updated `org.mockito:mockito-junit-jupiter:5.11.0` to `5.12.0`
* Updated `org.xmlunit:xmlunit-matchers:2.9.1` to `2.10.0`

#### Plugin Dependency Updates
Expand Down
13 changes: 13 additions & 0 deletions doc/requirements/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,19 @@ Covers:

Needs: impl, utest, itest

#### Customize Environment for GitHub Workflow `ci-build.yml`
`dsn~customize-build-process.ci-build.environment~1`

PK allows configuring a custom GitHub environment for `ci-build.yml`.

Rationale:
* Some projects use GitHub Environments to manually approve running expensive builds.

Covers:
* [`req~customize-build-process~0`](system_requirements.md#customize-build-process)

Needs: impl, utest

#### Customize GitHub Workflow `release.yml`
`dsn~customize-build-process.release~0`

Expand Down
11 changes: 11 additions & 0 deletions doc/user_guide/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ build:

Sonar will only run for the first version in the list.

#### Customize Workflow Environment

If your project requires running workflow `ci-build.yml` in a certain GitHub environment, you can specify it like this:

```yml
build:
workflows:
- name: "ci-build.yml"
environment: aws
```

#### Customize Workflow Steps

If your project requires additional or modified steps in the generated GitHub workflow `ci-build.yml` you can replace existing steps or insert additional steps:
Expand Down
2 changes: 1 addition & 1 deletion parent-pom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<minimum.maven.version>3.6.3</minimum.maven.version>
<junit.version>5.10.2</junit.version>
<xmlunit.version>2.10.0</xmlunit.version>
<mockito.version>5.11.0</mockito.version>
<mockito.version>5.12.0</mockito.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<gpg.skip>true</gpg.skip>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
<plugin>
<groupId>com.exasol</groupId>
<artifactId>error-code-crawler-maven-plugin</artifactId>
<version>2.0.1</version>
<version>2.0.3</version>
<executions>
<execution>
<phase>verify</phase>
Expand Down
2 changes: 1 addition & 1 deletion project-keeper/error_code_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ error-tags:
PK-CORE:
packages:
- com.exasol.projectkeeper
highest-index: 206
highest-index: 207
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,16 @@ private CustomWorkflow convertWorkflow(final Workflow workflow) {
supportedWorkflowNames)
.toString());
}
if (workflow.stepCustomizations == null || workflow.stepCustomizations.isEmpty()) {
throw new IllegalArgumentException(ExaError.messageBuilder("E-PK-CORE-203")
.message("Missing customized steps for workflow {{workflow name}} in file {{config file name}}.",
workflow.name, CONFIG_FILE_NAME)
.mitigation("Add at least one step or remove the workflow.").toString());
}
return CustomWorkflow.builder() //
.workflowName(workflow.name) //
.environment(workflow.environment) //
.steps(convertSteps(workflow.stepCustomizations)) //
.build();
}

private List<StepCustomization> convertSteps(final List<RawStepCustomization> stepCustomizations) {
return stepCustomizations.stream().map(this::convertStep).toList();
return Optional.ofNullable(stepCustomizations).orElseGet(Collections::emptyList) //
.stream().map(this::convertStep).toList();
}

private StepCustomization convertStep(final RawStepCustomization step) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ public void setExasolDbVersions(final List<String> exasolDbVersions) {
public static class Workflow {
/** Workflow name, e.g. {@code ci-build.yml} or {@code release.yml}. */
public String name;
/** GitHub environment, e.g. {@code aws}. */
public String environment;
/** List of customizations for the workflow. */
public List<RawStepCustomization> stepCustomizations;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,21 @@ FileTemplate createCiBuildWorkflow() {
buildOptions.getExasolDbVersions().stream().map(this::quote).collect(joining(", ")));
template.replacing("defaultExasolDbVersion", quote(buildOptions.getExasolDbVersions().get(0)));
}
// [impl->dsn~customize-build-process.ci-build~0]
return new ContentCustomizingTemplate(template,
new GitHubWorkflowStepCustomizer(findCustomizations(CI_BUILD_WORKFLOW_NAME), buildType.buildJobId));
final String buildJobId = buildType.buildJobId;
return createTemplate(template, CI_BUILD_WORKFLOW_NAME, buildJobId);
}

private FileTemplate createTemplate(final FileTemplateFromResource template, final String workflowName,
final String buildJobId) {
final Optional<CustomWorkflow> workflow = buildOptions.getWorkflow(workflowName);
final List<StepCustomization> customizations = workflow.map(CustomWorkflow::getSteps)
.orElseGet(Collections::emptyList);
final String environmentName = workflow.map(CustomWorkflow::getEnvironment).orElse(null);
return new ContentCustomizingTemplate(template, new GitHubWorkflowCustomizer(
// [impl->dsn~customize-build-process.ci-build~0]
new GitHubWorkflowStepCustomizer(customizations, buildJobId),
// [impl->dsn~customize-build-process.ci-build.environment~1]
new GitHubWorkflowEnvironmentCustomizer(buildJobId, environmentName)));
}

private List<StepCustomization> findCustomizations(final String workflowName) {
Expand Down Expand Up @@ -94,8 +106,9 @@ private FileTemplate createCustomizedWorkflow(final String workflowName, final S
final FileTemplateFromResource template = new FileTemplateFromResource(WORKFLOW_PATH + workflowName,
REQUIRE_EXACT);
templateCustomizer.accept(template);
final List<StepCustomization> customizations = findCustomizations(workflowName);
return new ContentCustomizingTemplate(template,
new GitHubWorkflowStepCustomizer(findCustomizations(workflowName), jobName));
new GitHubWorkflowCustomizer(new GitHubWorkflowStepCustomizer(customizations, jobName)));
}

enum CiTemplateType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ Map<String, Object> getEnv() {
return asMap(rawJob.get("env"));
}

public String getEnvironment() {
return (String) rawJob.get("environment");
}

public void setEnvironment(final String environmentName) {
rawJob.put("environment", environmentName);
}

private Predicate<? super Step> hasId(final String id) {
return step -> step.getId().equals(id);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.exasol.projectkeeper.validators.files;

import static java.util.Arrays.asList;

import java.util.List;

/**
* This class customizes a GitHub workflow by delegating to a list of {@link WorkflowCustomizer}s.
*/
class GitHubWorkflowCustomizer implements ContentCustomizingTemplate.ContentCustomizer {
private static final String GENERATED_COMMENT = "# This file was generated by Project Keeper.\n";
private final GitHubWorkflowIO yaml;
private final List<WorkflowCustomizer> customizer;

GitHubWorkflowCustomizer(final WorkflowCustomizer... customizer) {
this(GitHubWorkflowIO.create(), asList(customizer));
}

GitHubWorkflowCustomizer(final GitHubWorkflowIO yaml, final List<WorkflowCustomizer> customizer) {
this.yaml = yaml;
this.customizer = customizer;
}

@Override
public String customizeContent(final String content) {
final GitHubWorkflow workflow = yaml.loadWorkflow(content);
customizeWorkflow(workflow);
return GENERATED_COMMENT + yaml.dumpWorkflow(workflow);
}

private void customizeWorkflow(final GitHubWorkflow workflow) {
this.customizer.forEach(c -> c.applyCustomization(workflow));
}

/**
* Interface for customizing a GitHub workflow. Implementations of this interface can modify the given workflow as
* required.
*/
interface WorkflowCustomizer {
/**
* Apply the customization to the given workflow.
*
* @param workflow workflow to customize
*/
void applyCustomization(GitHubWorkflow workflow);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.exasol.projectkeeper.validators.files;

import com.exasol.errorreporting.ExaError;
import com.exasol.projectkeeper.validators.files.GitHubWorkflow.Job;

class GitHubWorkflowEnvironmentCustomizer implements GitHubWorkflowCustomizer.WorkflowCustomizer {

private final String environmentName;
private final String jobId;

GitHubWorkflowEnvironmentCustomizer(final String jobId, final String environmentName) {
this.jobId = jobId;
this.environmentName = environmentName;
}

// [impl->dsn~customize-build-process.ci-build.environment~1]
@Override
public void applyCustomization(final GitHubWorkflow workflow) {
if (environmentName == null) {
return;
}
final Job job = workflow.getJob(jobId);
if (job == null) {
throw new IllegalArgumentException(ExaError.messageBuilder("E-PK-CORE-207")
.message("GitHub Workflow does not have a job with ID {{job id}}", jobId).toString());
}
job.setEnvironment(this.environmentName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,17 @@
import com.exasol.projectkeeper.shared.config.workflow.StepCustomization;
import com.exasol.projectkeeper.validators.files.GitHubWorkflow.Job;

class GitHubWorkflowStepCustomizer implements ContentCustomizingTemplate.ContentCustomizer {
private static final String GENERATED_COMMENT = "# This file was generated by Project Keeper.\n";
class GitHubWorkflowStepCustomizer implements GitHubWorkflowCustomizer.WorkflowCustomizer {
private final List<StepCustomization> customizations;
private final GitHubWorkflowIO yaml;
private final String jobId;

GitHubWorkflowStepCustomizer(final List<StepCustomization> customizations, final String jobId) {
this(GitHubWorkflowIO.create(), customizations, jobId);
}

GitHubWorkflowStepCustomizer(final GitHubWorkflowIO yaml, final List<StepCustomization> customizations,
final String jobId) {
this.yaml = yaml;
this.customizations = customizations;
this.jobId = jobId;
}

@Override
public String customizeContent(final String content) {
final GitHubWorkflow workflow = yaml.loadWorkflow(content);
customizeWorkflow(workflow);
return GENERATED_COMMENT + yaml.dumpWorkflow(workflow);
}

private void customizeWorkflow(final GitHubWorkflow workflow) {
public void applyCustomization(final GitHubWorkflow workflow) {
final Job job = workflow.getJob(jobId);
for (final StepCustomization customization : customizations) {
applyCustomization(job, customization);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ on:
jobs:
linkChecker:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
shell: "bash"
Expand Down
Loading

0 comments on commit 7bc1ed1

Please sign in to comment.