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

feat: Add Github Actions support #717

Merged
merged 4 commits into from
Mar 5, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package tech.jhipster.lite.generator.githubactions.application;

import org.springframework.stereotype.Service;
import tech.jhipster.lite.generator.githubactions.domain.GithubActionsService;
import tech.jhipster.lite.generator.project.domain.Project;

@Service
public class GithubActionsApplicationService {

private final GithubActionsService githubActionsService;

public GithubActionsApplicationService(GithubActionsService githubActionsService) {
this.githubActionsService = githubActionsService;
}

public void init(Project project) {
githubActionsService.init(project);
}

public void addYml(Project project) {
githubActionsService.addYmls(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package tech.jhipster.lite.generator.githubactions.domain;

import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.domain.ProjectRepository;

public class GithubActionsDomainService implements GithubActionsService {

public static final String GITHUB_ACTIONS_CI_SOURCE_FOLDER = "githubactions/.github/workflows/";
public static final String GITHUB_ACTIONS_CI_YML = "github-actions.yml.mustache";
public static final String GITHUB_ACTIONS_CI_DESTINATION_FOLDER = ".github/workflows/";

public static final String GITHUB_ACTIONS_SETUP_SOURCE_FOLDER = "githubactions/.github/actions/setup/";
public static final String GITHUB_ACTIONS_SETUP_YML = "action.yml.mustache";
public static final String GITHUB_ACTIONS_SETUP_DESTINATION_FOLDER = ".github/actions/setup/";

private final ProjectRepository projectRepository;

public GithubActionsDomainService(ProjectRepository projectRepository) {
this.projectRepository = projectRepository;
}

@Override
public void init(Project project) {
addYmls(project);
}

@Override
public void addYmls(Project project) {
projectRepository.template(
project,
GITHUB_ACTIONS_SETUP_SOURCE_FOLDER,
GITHUB_ACTIONS_SETUP_YML,
GITHUB_ACTIONS_SETUP_DESTINATION_FOLDER
);
projectRepository.template(project, GITHUB_ACTIONS_CI_SOURCE_FOLDER, GITHUB_ACTIONS_CI_YML, GITHUB_ACTIONS_CI_DESTINATION_FOLDER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package tech.jhipster.lite.generator.githubactions.domain;

import tech.jhipster.lite.generator.project.domain.Project;

public interface GithubActionsService {
void init(Project project);
Copy link
Member

Choose a reason for hiding this comment

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

I'd rename to: addGitHubActionsForMaven


void addYmls(Project project);
Copy link
Member

Choose a reason for hiding this comment

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

not sure we need this

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package tech.jhipster.lite.generator.githubactions.infrastructure.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tech.jhipster.lite.generator.githubactions.domain.GithubActionsDomainService;
import tech.jhipster.lite.generator.githubactions.domain.GithubActionsService;
import tech.jhipster.lite.generator.project.domain.ProjectRepository;

@Configuration
public class GithubActionsBeanConfiguration {

private final ProjectRepository projectRepository;

public GithubActionsBeanConfiguration(ProjectRepository projectRepository) {
this.projectRepository = projectRepository;
}

@Bean
public GithubActionsService githubActionsService() {
return new GithubActionsDomainService(projectRepository);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tech.jhipster.lite.generator.githubactions.infrastructure.primary.rest;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.jhipster.lite.generator.githubactions.application.GithubActionsApplicationService;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.infrastructure.primary.dto.ProjectDTO;
import tech.jhipster.lite.technical.infrastructure.primary.annotation.GeneratorStep;

@RestController
@RequestMapping("/api/github-actions/")
@Tag(name = "Github Actions")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
@Tag(name = "Github Actions")
@Tag(name = "GitHub Actions")

class GithubActionsResource {

private final GithubActionsApplicationService githubActionsApplicationService;

GithubActionsResource(GithubActionsApplicationService githubActionsApplicationService) {
this.githubActionsApplicationService = githubActionsApplicationService;
}

@Operation(summary = "Init Github Actions YML file")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
@Operation(summary = "Init Github Actions YML file")
@Operation(summary = "Add GitHub Actions YML files")

@ApiResponse(responseCode = "500", description = "An error occurred while initializing the github-actions.yml.mustache file")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
@ApiResponse(responseCode = "500", description = "An error occurred while initializing the github-actions.yml.mustache file")
@ApiResponse(responseCode = "500", description = "An error occurred while adding GitHub Actions")

@PostMapping("/init")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
@PostMapping("/init")
@PostMapping("/maven")

@GeneratorStep(id = "github-actions")
public void init(@RequestBody ProjectDTO projectDTO) {
Copy link
Member

Choose a reason for hiding this comment

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

I'd rename to addGitHubActionsForMaven, but if you don't like it, simply ignore my comment

Project project = ProjectDTO.toProject(projectDTO);
githubActionsApplicationService.init(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@tech.jhipster.lite.BusinessContext
package tech.jhipster.lite.generator.githubactions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: 'Setup'
description: 'Setup environment with Java 17, Node 16.14.0'
runs:
using: 'composite'
steps:
- name: 'Setup: Node.js'
uses: actions/setup-node@v2.5.0
with:
node-version: 16.14.0
- name: 'Setup: update NPM'
shell: bash
run: npm install -g npm
- name: 'Setup: Java 17'
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: '17.x'
- name: 'Setup: check tools'
shell: bash
run: |
node -v
npm -v
java -version
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: GitHub Actions
on: [push]
jobs:
#--------------------------------------------------
# Build and Tests the project on Linux
#--------------------------------------------------
tests:
name: tests
runs-on: ubuntu-latest
timeout-minutes: 2
steps:{{=<% %>=}}
- name: 'Setup: checkout project'
uses: actions/checkout@v2
- name: 'Setup: environment'
id: setup
uses: ./.github/actions/setup
- name: 'Init: cache local Maven repository'
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-<%={{ }}=%>
- name: 'Test: run tests'
run: |
chmod +x mvnw
./mvnw clean verify
Copy link
Member

Choose a reason for hiding this comment

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

Problem with indent

Suggested change
runs-on: ubuntu-latest
timeout-minutes: 2
steps:{{=<% %>=}}
- name: 'Setup: checkout project'
uses: actions/checkout@v2
- name: 'Setup: environment'
id: setup
uses: ./.github/actions/setup
- name: 'Init: cache local Maven repository'
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-<%={{ }}=%>
- name: 'Test: run tests'
run: |
chmod +x mvnw
./mvnw clean verify
runs-on: ubuntu-latest
timeout-minutes: 20
steps:{{=<% %>=}}
- name: 'Setup: checkout project'
uses: actions/checkout@v2
- name: 'Setup: environment'
id: setup
uses: ./.github/actions/setup
- name: 'Init: cache local Maven repository'
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: 'Test: run tests'
run: |
chmod +x mvnw
./mvnw clean verify

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tech.jhipster.lite.generator.githubactions.application;

import static tech.jhipster.lite.TestUtils.tmpProject;
import static tech.jhipster.lite.generator.githubactions.application.GithubActionsAssertFiles.assertFilesYml;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import tech.jhipster.lite.IntegrationTest;
import tech.jhipster.lite.generator.project.domain.Project;

@IntegrationTest
class GithubActionsApplicationServiceIT {

@Autowired
GithubActionsApplicationService githubActionsApplicationService;

@Test
void shouldInit() {
Project project = tmpProject();

githubActionsApplicationService.init(project);

assertFilesYml(project);
}

@Test
void shouldAddYmls() {
Project project = tmpProject();

githubActionsApplicationService.addYml(project);

assertFilesYml(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package tech.jhipster.lite.generator.githubactions.application;

import static tech.jhipster.lite.TestUtils.assertFileExist;

import tech.jhipster.lite.generator.project.domain.Project;

public class GithubActionsAssertFiles {

public static void assertFilesYml(Project project) {
assertFileExist(project, ".github/workflows/github-actions.yml");
assertFileExist(project, ".github/actions/setup/action.yml");
}

public static void assertFilesGithubActions(Project project) {
assertFilesYml(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package tech.jhipster.lite.generator.githubactions.domain;

import static org.assertj.core.api.Assertions.assertThatCode;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static tech.jhipster.lite.TestUtils.tmpProject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import tech.jhipster.lite.UnitTest;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.domain.ProjectRepository;

@UnitTest
@ExtendWith(MockitoExtension.class)
class GithubActionsDomainServiceTest {

@Mock
private ProjectRepository projectRepository;

@InjectMocks
private GithubActionsDomainService githubActionsDomainService;

@Test
void shouldInit() {
Project project = tmpProject();

assertThatCode(() -> githubActionsDomainService.init(project)).doesNotThrowAnyException();
}

@Test
void shouldAddYml() {
Project project = tmpProject();

assertThatCode(() -> githubActionsDomainService.addYmls(project)).doesNotThrowAnyException();

verify(projectRepository)
.template(any(Project.class), eq("githubactions/.github/actions/setup/"), eq("action.yml.mustache"), eq(".github/actions/setup/"));
verify(projectRepository)
.template(any(Project.class), eq("githubactions/.github/workflows/"), eq("github-actions.yml.mustache"), eq(".github/workflows/"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package tech.jhipster.lite.generator.githubactions.infrastructure.config;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import tech.jhipster.lite.IntegrationTest;
import tech.jhipster.lite.generator.githubactions.domain.GithubActionsDomainService;
import tech.jhipster.lite.generator.init.domain.InitDomainService;

@IntegrationTest
class GithubActionsBeanConfigurationIT {

@Autowired
ApplicationContext applicationContext;

@Test
void shouldGetBean() {
assertThat(applicationContext.getBean("githubActionsService")).isNotNull().isInstanceOf(GithubActionsDomainService.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package tech.jhipster.lite.generator.githubactions.infrastructure.primary.rest;

import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static tech.jhipster.lite.TestUtils.convertObjectToJsonBytes;
import static tech.jhipster.lite.TestUtils.readFileToObject;
import static tech.jhipster.lite.generator.githubactions.application.GithubActionsAssertFiles.assertFilesGithubActions;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import tech.jhipster.lite.IntegrationTest;
import tech.jhipster.lite.common.domain.FileUtils;
import tech.jhipster.lite.generator.githubactions.application.GithubActionsApplicationService;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.infrastructure.primary.dto.ProjectDTO;

@IntegrationTest
@AutoConfigureMockMvc
class GithubActionsResourceIT {

@Autowired
MockMvc mockMvc;

@Autowired
GithubActionsApplicationService githubActionsApplicationService;

@Test
void shouldInit() throws Exception {
ProjectDTO projectDTO = readFileToObject("json/chips.json", ProjectDTO.class).folder(FileUtils.tmpDirForTest());

mockMvc
.perform(post("/api/github-actions/init").contentType(MediaType.APPLICATION_JSON).content(convertObjectToJsonBytes(projectDTO)))
.andExpect(status().isOk());

Project project = ProjectDTO.toProject(projectDTO);
assertFilesGithubActions(project);
}
}