I recently was playing with Github Actions and a Grails 3 app. Was a bit of trial and error though I finally got a working CI workflow.
Github recently added build caching with limitations - this dramatically speeds up your CI builds.
A nice aspect about Actions is you can have actions based on not only pushes/PRs/tags but also things like Github comments. For example /rebase
- there's an entire marketplace of actions you can try out.
我评论了yml文件,以帮助您了解发生了什么以及它如何工作。
可以在以下位置找到此yml文件的完整语法:
我还在下面包括了定制的测试报告-因为没有“结果”步骤可以查看junit类型的报告。 您可以在yml的下面找到它。
.github / workflows / grails.yml
name: Grails CI
# When this workflow will run - here it will run on all pushes but
# not on branch 'master
on:
push:
branches-ignore:
- 'master'
# A list jobs to run when the condition is met - here we've parallelized
# the build to run test, integrationTest, and assemble.
jobs:
test:
runs-on: ubuntu-latest
# A list of Docker containers you require to run the test
services:
postgres:
image: postgres:latest
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
# Steps in this build
steps:
- uses: actions/checkout@v1
# We are caching the node_modules, ~/.gradle and app/.gradle
# to speed up our build. Caches are automatically stored and restored
# based on a file hash - in this case yarn.lock and build.gradle
- name: Cache node modules
uses: actions/cache@v1
with:
path: src/main/vue/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-node-
- name: Cache .gradle
uses: actions/cache@v1
with:
path: .gradle
key: ${{ runner.os }}-dotgradle-${{ hashFiles('**/build.gradle') }}
restore-keys: |
${{ runner.os }}-dotgradle-
- name: Cache gradle
uses: actions/cache@v1
with:
path: /home/runner/.gradle
key: ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}
restore-keys: |
${{ runner.os }}-gradle-
# Setup JDK 8
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
# Finally run the test.
- name: test
run: ./gradlew test --no-daemon
# Integration and assemble are much the same
# though it's yml so not DRY - omitted the copy/paste
integrationTest:
steps:
- name: integrationTest
run: ./gradlew integrationTest --no-daemon
assemble:
steps:
- name: assemble
run: ./gradlew assemble --no-daemon
这是一个测试格式化程序,它为您提供了Spock错误,可以很好地将其stdout进行调试以及摘要:
.gradle / testFormatter.gradle
// From https://stackoverflow.com/a/40656862
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
tasks.withType(Test) {
testLogging {
// set options for log level LIFECYCLE
events TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED
exceptionFormat TestExceptionFormat.SHORT
showExceptions true
showCauses true
showStackTraces true
// set options for log level DEBUG and INFO
debug {
events TestLogEvent.STARTED,
TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED
exceptionFormat TestExceptionFormat.SHORT
}
info.events = debug.events
info.exceptionFormat = debug.exceptionFormat
afterSuite { desc, result ->
if (!desc.parent) { // will match the outermost suite
def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)"
def startItem = '| ', endItem = ' |'
def repeatLength = startItem.length() + output.length() + endItem.length()
println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
}
}
}
}