显示导航

将提交信息添加到你的 Grails 应用程序

了解应用程序正在运行的确切代码版本非常重要

作者:Colin Harrington

Grails 版本 3.3.1

1 Grails 培训

Grails 培训 - 由创建和积极维护 Grails 框架的团队开发并提供!

2 开始使用

在本指南中,我们将向你的 grails 构建工件和正在运行的应用程序添加 Git 提交信息。保存你的提交信息随时可用有很多好处

  • 提交信息封装在构建工件中

  • 快速可靠的方式识别在一个环境中运行的是哪段特定代码

  • 此解决方案不依赖外部跟踪机制

  • 在调查问题时具有透明度和可复制性

如果你喜欢总结,请查看 tl;dr

2.1 你需要什么

若要完成此指南,你需要以下内容

  • 一些时间

  • 一个合适的文本编辑器或 IDE

  • 安装 JDK 1.7 或更高版本,并且正确配置了 JAVA_HOME

2.2 如何完成此指南

按照以下步骤开始操作

Grails 指南代码库包含两个文件夹

  • initial 初始项目。通常是一个 Grails 应用程序,其中带有可帮助您抢先一步的其他代码。

  • complete 已完成的代码。它是根据指南提出的步骤来处理,并将这些更改应用于initial 文件夹的结果。

若要完成指南,请转到initial 文件夹

  • cd 进入grails-guides/adding-commit-info/initial

,并按照下一部分中的说明操作。

如果您cd 进入grails-guides/adding-commit-info/complete,则可以直接转到已完成的代码

3 历史记录

过去有几种不同的方法来完成此任务,值得一提。

3.1 早期方法

在 Grails 的早期,有方法可以进入诸如 scripts/_Events.groovy 中的 eventCompileStart 等构建事件,以获取 git-sha ("git rev-parse HEAD".execute().text),并根据此篇文章所述将其作为应用程序的一部分包含在内。

3.2 application.properties

Grails 2.x 及以下版本有一个 application.properties,可将其用作存储提交属性。Grails 用于存储其应用程序名称和版本的地方也是这里。

在此示例中,需要一种机制将提交信息添加到application.properties/更新application.properties,这可能是构建系统在构建 war 之前会将 git 提交信息作为构建步骤添加的情况。

在将提交信息添加到application.properties 之后,我们可以通过多种方式来访问该元数据

  • 通过 grailsApplication.metadata['git.sha'] 访问 GrailsApplication

  • 在视图中使用标记库 <g:meta name='git.sha'/>

3.3 构建信息插件

另一种流行于 Grails 2.x 的方法是使用构建信息插件。构建信息插件通过使用 Jenkins 等构建系统可用环境变量来发挥作用。

  • BUILD_NUMBER

  • BUILD_ID

  • BUILD_TAG

  • SVN_REVISION

  • GIT_COMMIT

  • GIT_BRANCH

这些值可以通过访问/buildInfo 端点来使用。

4 编写应用程序

有两个基本步骤

让我们开始吧!

4.1 Gradle 插件

Grails 3.x 的一个特点是应用程序随附打包的基于 Gradle 的构建工具。

我们可以利用gradle-git-properties 插件,而不用实现自己的机制来获取 git 提交信息。此插件的目的是获取提交信息并将其存储在名为 git.properties 的文件中

添加 Gradle 插件的过程相对简单。包括以下几个步骤。

  1. 添加依赖项至 build.gradle 中的 buildscript { …​ } 块。这意味着您将把依赖项添加到构建而不是可交付应用程序中。

  2. 确保将通过相应的 maven 存储库解析构建脚本依赖项

  3. 应用插件

/complete/build.gradle
buildscript {
    repositories {
        maven { url "https://plugins.gradle.org.cn/m2/" }
    }
    dependencies {
        classpath "gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:1.4.17"
    }
}
apply plugin: "com.gorylenko.gradle-git-properties"

现在,每次编译或运行应用程序(特别是 JavaPlugin 的classes 任务)时,您都会发现已生成 git.properties。在本地运行应用程序时,可在 /build/resources/main/git.properties 中找到此文件。将其打包为 war 或独立 jar 时,您将在 WEB-INF/classes 中找到 git.properties

$ unzip -l ./build/libs/complete-0.1.war | grep git.properties
      276  2017-02-02 11:53   WEB-INF/classes/git.properties

检查 git.properties 会显示已捕获到的提交信息

git.branch=master
git.commit.id=777d70650bb055862436fc59071072aae8cd0ddd
git.commit.id.abbrev=777d706
git.commit.user.name=Colin Harrington
[email protected]
git.commit.message.short=Adding gradle-git-properties plugin
git.commit.message.full=Adding gradle-git-properties plugin

git.commit.time=1487262171

可以通过配置 gradle 任务(在 build.gradle 中)来配置/影响生成 git.properties 的方式。

gitProperties {
    dateFormat = "yyyy-MM-dd'T'HH:mmZ"
    dateFormatTimeZone = "CST"
}

4.2 Spring Boot 促动器端点

现在我们已经通过 git.properties 文件捕获了 git 提交信息并将其包含在我们应用程序中,是时候使用它了。

Grails 3.x 基于 Spring Boot,我们可以利用已经包含在应用程序中的一些底层工具。

Spring Boot 包含许多其他功能,可帮助您在将应用程序推送到生产环境后对其进行监控和管理。可以选择使用 HTTP 端点、JMX 甚至远程外壳(SSH 或 Telnet)管理和监控应用程序。可以将审计、运行状况和指标收集自动应用于您的应用程序。其中一些生产就绪功能已经内置其中。

Spring Boot 中内置了一个名为 spring-boot-actuator 的模块,可提供这些端点。默认情况下,端点被禁用,因此第一步是启用它们。


如果打开 grails-app/conf/application.yml,您将找到一个类似这样的配置块

grails-app/conf/application.yml
# Spring Actuator Endpoints are Disabled by Default
endpoints:
    enabled: false

您只需通过设置 enabled: true 来启用促动器端点

/grails-app/conf/application.yml
endpoints:
    enabled: true

5 运行应用程序

要运行应用程序,请使用 ./gradlew bootRun 命令,该命令将在 8080 端口启动应用程序。

启用促动器端点之后,在运行应用程序时,可以转到 http://localhost:8080/info 中的 /info 端点,您应当会看到类似以下内容的 JSON 格式的信息

{
    app: {
        name: "complete",
        grailsVersion: "3.2.6",
        version: "0.1"
    },
    git: {
        commit: {
            time: "2017-02-16T10:31-0600",
            id: "2f27f2c"
        },
        branch: "master"
    }
}

6 配置

您可能不想启用所有默认促动器端点。如果您只想启用 info 端点,您需要通过配置设置 endpoints.info.enabled=true 并保留 endpoints.enabled=false

# Spring Actuator Endpoints are Disabled by Default
endpoints:
    enabled: false
    info:
        enabled: true
你应当知道如果开启了执行器端点中的全部端点,可能会开启若干你可能不想暴露的端点。有些端点暴露敏感信息,你可能需要对它们进行保护或禁用。请查看文档以获取更多信息 https://docs.springframework.org.cn/spring-boot/docs/current/reference/html/production-ready-endpoints.html

6.1 配置将展示的提交信息

你可能已经注意到,/info 端点仅包含 git.properties 中属性的一个子集,如简写 sha、提交时间和分支。你可以通过设置 management.info.git.mode=full 来通过配置显示完整的 git 属性。

你将在 grails-app/conf/application.yml 中设置这些值。

/complete/grails-app/conf/application.yml
management:
    info:
        git:
            mode: full

随后,当你重启应用程序并在 http://localhost:8080/info 访问 /info 端点时,你应当看到类似这样的信息

{
    app: {
        name: "complete",
        grailsVersion: "3.2.6",
        version: "0.1"
    },
    git: {
        commit: {
            message: {
                full: "Enabling Spring Actuator Endpoints",
                short: "Enabling Spring Actuator Endpoints"
            },
            time: "2017-02-16T11:46-0600",
            id: "1695eb2c925e486acb962acf771f813a36568719",
            id.abbrev: "1695eb2",
            user: {
                email: "[email protected]",
                name: "Colin Harrington"
            }
        },
        branch: "master"
    }
}
在底层,此行为由 GitInfoContributor 处理。 InfoEndpoint 是可扩展的,并会汇总所有启用了实现 org.springframework.boot.actuate.info.InfoContributor 的 bean。

此外,我们可以添加一个功能性测试来验证 Git 信息是否显示在 rest 响应中。

grails-datastore-rest-client 插件添加到你的 dependencies 区块。

/complete/build.gradle
    testCompile "org.grails:grails-datastore-rest-client"
/complete/src/integration-test/groovy/demo/InfoSpec.groovy
package demo

import grails.plugins.rest.client.RestBuilder
import grails.testing.mixin.integration.Integration
import grails.transaction.Rollback
import spock.lang.Specification

@Integration
class InfoSpec extends Specification {

    def "test git commit info appears in JSON"() {
        given:
        RestBuilder rest = new RestBuilder()

        when:
        def resp = rest.get("http://localhost:${serverPort}/info") {
            header("Accept", "application/json")
        }

        then:
        resp.statusCode.value() == 200
        resp.json
        resp.json.git
        resp.json.git.commit
        resp.json.git.commit.message
        resp.json.git.commit.time
        resp.json.git.commit.id
        resp.json.git.commit.user
        resp.json.git.branch
    }
}

6.2 环境配置

向你的应用程序添加 git 提交信息有助于调试和透明度。默认简单模式仅暴露 sha、时间和分支名称。有些组织希望在其更敏感的环境中进一步限制提交的信息。

一种方法是利用 按环境配置 来根据环境启用/禁用并不同地配置端点。例如,如果你仅希望在生产中启用简单模式,你可以使用以下配置

/complete/grails-app/conf/application.yml
environments:
    production:
        management:
            info:
                git:
                    mode: simple

6.3 必要时保护你的端点

除了特定于环境的配置之外,一些组织可能希望仅允许经过身份验证的用户或特定角色集使用。可以通过插入你的安全插件来实现此目的。我们以 Spring Security 作为一个规范示例。 /info 端点不是 Grails 控制器,因此如果你使用默认注释基础方法,你将需要配置 grails.plugin.springsecurity.controllerAnnotations.staticRules

grails.plugin.springsecurity.controllerAnnotations.staticRules = [
   [pattern: '/',               access: ['permitAll']],
   [pattern: '/error',          access: ['permitAll']],
   [pattern: '/index',          access: ['permitAll']],
   // ...
   [pattern: '/info',           access: ['ROLE_ADMIN', 'isFullyAuthenticated()']]
]

基于 RequestMaps简单映射 的安全配置方法会用到请求的网址,因此不需要任何特殊操作。有关详细信息,请参阅 Spring Security Core 插件文档

7 tl;dr(太长;免读)

概要

  • 添加 gradle-git-properties 插件

  • 通过使用 endpoints.info.enabled=trueendpoints.enabled=true 来启用执行器端点

  • 配置保护 端点,并按需操作

  • …​

  • 清楚地了解到底运行了哪些版本的代码(收益!