前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >GitHub Actions初体验:自动化校验和部署Java项目

GitHub Actions初体验:自动化校验和部署Java项目

作者头像
小草学习屋
发布2023-11-22 09:49:22
3580
发布2023-11-22 09:49:22
举报
文章被收录于专栏:小草学习屋小草学习屋

文章总结了使用GitHub Actions自动化校验和部署Java项目的实践经验,提高效率和标准化CI/CD流程。

GitHub Action 简介

GitHub Actions是GitHub的CI/CD服务。它可以自动和规范项目的CI/CD流程,减少人工成本,降低人人因风险。

例如,我们可以在项目P有新的Pull Request时,对PR作格式校验、构建检测等来检测PR是否符合要求; 在发布Tag时部署到容器或发布到公共仓库等。

下面以Gradle方式构建的Java项目为例,说明如何使用GitHub Actions优化项目CI/CD流程。

优化CI流程

为了保证代码质量,项目的PR需要符合下述需求:

  • 符合Java代码规范
  • 通过Gradle Build

怎么用GitHub Actions实现?

  1. 定义一个workflow.yml文件
  2. 在里面加入需要的流程

下面是在PR时对代码进行Gradle Build的workflow.yml:

代码语言:javascript
复制
name: Java CI
# 触发事件,此处为PR
on: [pull_request]
# 一个workflow可包含多个jobs,每个jobs运行在不同的虚拟机,可根据需求设置并行或者串行运行
jobs:
# 该job的名称
  build:
# 在ubuntu下运行
    runs-on: ubuntu-latest
# 一个job可以有多个step(步骤),每个step按顺序执行,每个step可以运行一个action(动作)。
    steps:
      - uses: actions/checkout@v2
      # 步骤名称
      - name: Set up JDK 11
        # 使用哪个action,可以在MarketPlace上查找需要的action
        uses: actions/setup-java@v2
        # 指定action的参数
        with:
          java-version: '11'
          distribution: 'adopt'
      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
      - name: Build with Gradle
        run: ./gradlew build

在项目的.github/workflows文件夹增加这个文件,就可以在PR时自动触发。对代码进行校验同理。

GitHub文档还是很友善的,可以在官方文档中找到示例workflow语法等。 结合文档搜索框和Stack overflow使用更佳。

小tips:为了测试workflow,需要多次触发PR、Push等行为,很不方便。可以使用act等工具在本地触发。

优化CD流程

Java项目要被其他开发者使用,需要部署到Maven中央仓库。此外,项目需要更新和发布tag,在release中说明更新的特性、变更记录等。

因此我们要做2件事情:发布release、部署到Maven仓库。

怎么结合Github Actions?

方案可以有两种:

  1. PR合进主干时触发发布release(包含创建tag)、部署到Maven仓库操作。
  2. 发布release时触发部署到Maven仓库操作。

方案一可以实现全流程自动部署。在评审人将代码合进主干时,需要按照一定格式填写合代码的信息,让action从里面拿去需要修改的版本号和release说明。

这种方案对评审人不友好,因为他需要了解此次变更细节,按照格式填写release信息;实现成本高,workflow也更复杂,需要从触发事件中获取数据、使用自动增加版本号、发布release等action,还要考虑异常防护措施。

方案二需要在Github上发布release,这个事件自动触发部署到Maven仓库操作。这种方式需要人工在页面操作,但是可以由熟悉变更的人发布release(自动创建tag),实现成本低,workflow更简单。

经过讨论,我们选择了方案二,实现发布release时触发部署到Maven仓库操作。GitHbu非常贴心,提供了示例, 但还需要进行以下补充:

  1. 对tag进行格式检测
  2. 使用sign插件对项目文件签名

第一点,因为项目版本号变更遵循语义化版本,所以要先校验tag是否符合规范。官方非常贴心地提供了校验的正则表达式, 因此我们可以用在正则来校验。

第二点,是发布到maven中央仓库的必需项,因此不能跳过。 人工发布时使用的命令是:

代码语言:javascript
复制
./gradlew publish -Psigning.keyId=${signing_key_id} -Psigning.password=${PASSWORD} -Psigning.secretKeyRingFile=${file_path}

在命令中传入参数和私钥文件进行签名,网上搜到的教程大部分也是这样做的。这种做法会存在安全隐患

  • workflow工作流会打印出敏感信息(尽管是加密后的)
  • 虚拟机中会存在私钥文件

可以从这篇文章中看到,当程序被恶意入侵,有很多种方式可以窃取密钥。

因此,我们选择将所有密钥都放进环境变量中,来可能保证密钥的安全性。

在gradle文档中可以找到使用环境变量中的密钥签名方式。因此,我们把密钥放进GitHub Secrets中, 并在Github Actions中使用它

另外,为了防止变更中忘记修改版本号,在PR时触发自动发布task lists,来提醒开发者更新版本。

实践

整体思路:

  1. PR时检测代码规范
  2. PR时校验Gradle Build是否通过
  3. PR时发布task lists
  4. Release tag时自动部署

1、2比较简单,搜索即可。此处给出3、4的workflow文件以作参考。

PR时发布task lists:

代码语言:javascript
复制
name: Comment on Pull Request

on:
  pull_request:

jobs:

  # pr时自动创建待完成任务
  comment-on-pr:
    runs-on: ubuntu-latest
    steps:
      - name: comment PR
        uses: unsplash/comment-on-pr@v1.3.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          msg: "请完成以下事项:\n - [ ] 更新build.gradle中的version "

效果如图:

image.png
image.png

Release tag时自动部署:

代码语言:javascript
复制
name: Gradle Publish

on:
  release:
    types: published
jobs:

  # 校验tag是否满足语义化版本格式
  check-tag:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Regex Match
        id: regex-match
        run: |
          result=$(printf ${{github.ref_name}} | perl -ne 'printf if /^v(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/')
          echo "::set-output name=result::$result"
      - name: Check Tag
        if: ${{ steps.regex-match.outputs.result != github.ref_name }}
        uses: actions/github-script@v4
        with:
          script: core.setFailed('Invalid Tag:${{github.ref_name}}')

  # Push Tag时自动发布新版本到Maven中央仓库
  publish:
    needs: [check-tag]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Java
        uses: actions/setup-java@v2
        with:
          java-version: '8'
          distribution: 'adopt'
      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
      # 发布项目
      - name: Publish
        run: ./gradlew publish
        env:
          SONATYPE_NEXUS_USERNAME: ${{secrets.SONATYPE_NEXUS_USERNAME}}
          SONATYPE_NEXUS_PASSWORD: ${{secrets.SONATYPE_NEXUS_USERNAME}}
          ORG_GRADLE_PROJECT_signingKey: ${{secrets.SIGNING_KEY}}
          ORG_GRADLE_PROJECT_signingPassword: ${{secrets.SIGNING_PASSWORD}}

小结

文章总结了使用GitHub Actions自动化校验和部署Java项目的实践经验,提高效率和标准化CI/CD流程。

这个过程中,一些看似“就该这么做”的决策其实经过很多讨论和思考。例如,GPG加密方式,我开始没考虑到安全问题,还是经过别人的提点才意识到。

我们总是会想,“这个东西好像没有难点,当时就只有这种方案。”

真是这样吗?

换做经验丰富的工程师,他会提出你想不到的质疑;换做经验尚浅的学生, 他会提出更不成熟的方案。而这些想不到的质疑、被默认否认的方案,就是经过思考得到的结果。

结果很重要,思考更重要。忘记思考,下次的结果只会更差,不会更好。这就是我很菜,但仍然坚持总结的原因。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • GitHub Action 简介
  • 优化CI流程
  • 优化CD流程
  • 实践
  • 小结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档