แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

ฉันมักจะต้องสร้างไปป์ไลน์สำหรับการสร้างโปรเจ็กต์ใน Java บางครั้งก็เป็นโอเพ่นซอร์สบางครั้งก็ไม่ใช่ ฉันเพิ่งตัดสินใจลองย้ายที่เก็บข้อมูลบางส่วนจาก Travis-CI และ TeamCity ไปยัง GitHub Actions และนี่คือผลลัพธ์ที่ได้

เราจะทำอะไรโดยอัตโนมัติ?

ก่อนอื่น เราต้องการโปรเจ็กต์ที่เราจะทำให้เป็นอัตโนมัติ มาสร้างแอปพลิเคชันขนาดเล็กใน Spring boot / Java 11 / Maven กัน สำหรับวัตถุประสงค์ของบทความนี้ เราจะไม่สนใจตรรกะของแอปพลิเคชันเลย เนื่องจากโครงสร้างพื้นฐานรอบๆ แอปพลิเคชันมีความสำคัญสำหรับเรา ดังนั้นตัวควบคุม REST API แบบธรรมดาก็เพียงพอสำหรับเรา

คุณสามารถดูแหล่งที่มาได้ที่นี่: github.com/antkorwin/github-actions ทุกขั้นตอนของการสร้างไปป์ไลน์จะสะท้อนให้เห็นในคำขอดึงสำหรับโปรเจ็กต์นี้

จิระกับการวางแผน

คุ้มค่าที่จะบอกว่าเรามักจะใช้ JIRA เป็นตัวติดตามปัญหา ดังนั้นเรามาสร้างบอร์ดแยกต่างหากสำหรับโปรเจ็กต์นี้และเพิ่มประเด็นแรกที่นั่น:

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

อีกไม่นานเราจะกลับไปสู่สิ่งที่น่าสนใจที่ JIRA และ GitHub สามารถนำเสนอร่วมกันได้

เราทำให้การประกอบโครงการเป็นแบบอัตโนมัติ

โปรเจ็กต์ทดสอบของเราสร้างผ่าน maven ดังนั้นการสร้างมันจึงค่อนข้างง่าย ทั้งหมดที่เราต้องการคือ mvn clean package

ในการดำเนินการนี้โดยใช้ Github Actions เราจะต้องสร้างไฟล์ในพื้นที่เก็บข้อมูลที่อธิบายขั้นตอนการทำงานของเรา ซึ่งสามารถทำได้ด้วยไฟล์ yml ทั่วไป ฉันไม่สามารถพูดได้ว่าฉันชอบ "การเขียนโปรแกรม yml" แต่เราจะทำอะไรได้บ้าง - เราทำใน .github/ directory workflow/ file build.yml ซึ่งเราจะอธิบายการดำเนินการเมื่อสร้างสาขาหลัก:

name: Build

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - 'master'

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Package
        run: mvn -B clean package -DskipTests

on — นี่คือคำอธิบายของเหตุการณ์ที่สคริปต์ของเราจะเปิดตัว

เมื่อ: pull_request/push — ระบุว่าจำเป็นต้องเปิดใช้งานเวิร์กโฟลว์นี้ทุกครั้งที่มีการพุชไปยังต้นแบบและสร้างคำขอดึง

ต่อไปนี้เป็นคำอธิบายของงาน (ตำแหน่งงาน) และขั้นตอนการดำเนินการ (ทำตามขั้นตอน) สำหรับแต่ละงาน

วิ่งต่อไป - ที่นี่เราสามารถเลือกระบบปฏิบัติการเป้าหมายได้ น่าแปลกใจที่คุณสามารถเลือก Mac OS ได้ แต่ในที่เก็บข้อมูลส่วนตัวจะมีราคาค่อนข้างแพง (เทียบกับ Linux)

ใช้ อนุญาตให้คุณนำการกระทำอื่น ๆ มาใช้ซ้ำได้ เช่น การใช้การดำเนินการ actions/setup-java ที่เราติดตั้งสภาพแวดล้อมสำหรับ Java 11

โดย กับ เราสามารถระบุพารามิเตอร์ที่เราเปิดใช้การดำเนินการได้ โดยพื้นฐานแล้วนี่คืออาร์กิวเมนต์ที่จะถูกส่งไปยังการดำเนินการ

สิ่งที่เหลืออยู่คือการรันโปรเจ็กต์บิวด์ด้วย Maven: run: mvn -B clean package ธง -B บอกว่าเราต้องการโหมดที่ไม่โต้ตอบเพื่อที่จู่ๆ Maven จะไม่ต้องการถามอะไรเรา

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

ยอดเยี่ยม! ตอนนี้ ทุกครั้งที่คุณผูกพันกับต้นแบบ การสร้างโปรเจ็กต์จะเริ่มต้นขึ้น

เปิดตัวการทดสอบอัตโนมัติ

การประกอบเป็นสิ่งที่ดี แต่ในความเป็นจริง โครงการสามารถประกอบได้อย่างปลอดภัย แต่ใช้งานไม่ได้ ดังนั้นขั้นตอนต่อไปคือทำให้การทดสอบทำงานโดยอัตโนมัติ นอกจากนี้ การดูผลการผ่านการทดสอบเมื่อคุณทำการตรวจสอบ PR นั้นค่อนข้างสะดวก - คุณจะรู้แน่นอนว่าการทดสอบผ่านไปและไม่มีใครลืมเปิดสาขาก่อนทำการรวม

เราจะทำการทดสอบเมื่อสร้างคำขอดึงและรวมเข้ากับต้นแบบ และในเวลาเดียวกันเราจะเพิ่มการสร้างรายงานเกี่ยวกับการครอบคลุมของโค้ด

name: Build

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - 'master'

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Verify
        run: mvn -B clean verify
      - name: Test Coverage
        uses: codecov/codecov-action@v1
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

เพื่อให้ครอบคลุมการทดสอบ ฉันใช้ codecov ร่วมกับปลั๊กอิน jacoco codecov มีการดำเนินการของตัวเอง แต่ต้องมีโทเค็นเพื่อทำงานกับคำขอดึงของเรา:

${{ secrets.CODECOV_TOKEN }} — เราจะเห็นโครงสร้างนี้มากกว่าหนึ่งครั้ง ความลับเป็นกลไกในการจัดเก็บความลับใน GitHub เราสามารถเขียนรหัสผ่าน/โทเค็น/โฮสต์/url และข้อมูลอื่น ๆ ที่ไม่ควรรวมไว้ในฐานรหัสพื้นที่เก็บข้อมูลได้

คุณสามารถเพิ่มตัวแปรให้กับข้อมูลลับได้ในการตั้งค่าพื้นที่เก็บข้อมูลบน GitHub:

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

คุณสามารถรับโทเค็นได้ที่ codecov.io หลังจากการอนุญาตผ่าน GitHub หากต้องการเพิ่มโครงการสาธารณะ คุณเพียงแค่คลิกลิงก์ดังนี้: ชื่อผู้ใช้ GitHub/[ชื่อ repo]. คุณสามารถเพิ่มพื้นที่เก็บข้อมูลส่วนตัวได้ ในการดำเนินการนี้ คุณต้องให้สิทธิ์ codecov แก่แอปพลิเคชันใน Github

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

เพิ่มปลั๊กอิน jacoco ลงในไฟล์ POM:

<plugin>
	<groupId>org.jacoco</groupId>
	<artifactId>jacoco-maven-plugin</artifactId>
	<version>0.8.4</version>
	<executions>
		<execution>
			<goals>
				<goal>prepare-agent</goal>
			</goals>
		</execution>
		<!-- attached to Maven test phase -->
		<execution>
			<id>report</id>
			<phase>test</phase>
			<goals>
				<goal>report</goal>
			</goals>
		</execution>
	</executions>
</plugin>
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-surefire-plugin</artifactId>
	<version>2.22.2</version>
	<configuration>
		<reportFormat>plain</reportFormat>
		<includes>
			<include>**/*Test*.java</include>
			<include>**/*IT*.java</include>
		</includes>
	</configuration>
</plugin>

ตอนนี้บอท Codecov จะป้อนคำขอดึงแต่ละรายการของเราและเพิ่มกราฟการเปลี่ยนแปลงความครอบคลุม:

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

มาเพิ่มเครื่องวิเคราะห์แบบคงที่กันดีกว่า

ในโปรเจ็กต์โอเพ่นซอร์สส่วนใหญ่ของฉัน ฉันใช้โซนาร์คลาวด์สำหรับการวิเคราะห์โค้ดแบบคงที่ ซึ่งการเชื่อมต่อกับ travis-ci นั้นค่อนข้างง่าย ดังนั้นจึงเป็นขั้นตอนที่สมเหตุสมผลเมื่อย้ายไปยัง GitHub Actions เพื่อทำเช่นเดียวกัน ตลาดการดำเนินการเป็นสิ่งที่ดี แต่คราวนี้มันทำให้ฉันผิดหวังนิดหน่อย เพราะว่าฉันพบการกระทำที่ฉันต้องการและเพิ่มลงในขั้นตอนการทำงานโดยไม่ได้ตั้งใจ แต่ปรากฎว่าโซนาร์ไม่สนับสนุนการทำงานเพื่อวิเคราะห์โปรเจ็กต์บน maven หรือ gradle แน่นอนว่าสิ่งนี้เขียนไว้ในเอกสาร แต่ใครล่ะที่ได้อ่าน?!

การดำเนินการนี้เป็นไปไม่ได้ ดังนั้นเราจะดำเนินการผ่านปลั๊กอิน mvn:

name: SonarCloud

on:
  push:
    branches:
      - master
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  sonarcloud:
    runs-on: ubuntu-16.04
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Analyze with SonarCloud
#       set environment variables:
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
#       run sonar maven plugin:
        run: mvn -B verify sonar:sonar -Dsonar.projectKey=antkorwin_github-actions -Dsonar.organization=antkorwin-github -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.jacoco.xmlReportPaths=./target/site/jacoco/jacoco.xml

SONAR_TOKEN - สามารถรับได้ที่ sonarcloud.io และคุณต้องลงทะเบียนเป็นความลับ GITHUB_TOKEN - นี่คือโทเค็นในตัวที่ GitHub สร้างขึ้น ด้วยความช่วยเหลือซึ่ง sonarcloud[bot] จะสามารถเข้าสู่ระบบ Git เพื่อฝากข้อความถึงเราในคำขอดึง

Dsonar.projectKey — ชื่อของโปรเจ็กต์ในโซนาร์ คุณสามารถดูได้ในการตั้งค่าโปรเจ็กต์

Dsonar.องค์กร — ชื่อองค์กรจาก GitHub

เราทำคำขอดึงและรอให้ sonarcloud[bot] เข้ามาแสดงความคิดเห็น:

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

การจัดการการปล่อย

บิลด์ได้รับการกำหนดค่าแล้ว ดำเนินการทดสอบแล้ว และเราสามารถเผยแพร่ได้ มาดูกันว่า GitHub Actions ช่วยให้การจัดการ Release ง่ายขึ้นมากได้อย่างไร

ที่ทำงาน ฉันมีโปรเจ็กต์ที่มีฐานโค้ดอยู่ใน bitbucket (ทุกอย่างเหมือนในเรื่องนั้น “ฉันเขียนถึง bitbucket ในระหว่างวัน และใช้งาน GitHub ตอนกลางคืน”) น่าเสียดายที่ bitbucket ไม่มีเครื่องมือการจัดการการเผยแพร่ในตัว นี่เป็นปัญหา เนื่องจากในแต่ละรีลีส คุณต้องสร้างเพจมาบรรจบกันด้วยตนเอง และโยนฟีเจอร์ทั้งหมดที่รวมอยู่ในรีลีสไปที่นั่น ค้นหาผ่านวังแห่งจิตใจ งานในจิรา กระทำในที่เก็บข้อมูล มีโอกาสมากมายที่จะทำผิดพลาด คุณสามารถลืมบางสิ่งบางอย่างหรือป้อนบางสิ่งที่เผยแพร่ไปแล้วครั้งล่าสุด บางครั้งก็ไม่ชัดเจนว่าจะจัดประเภทคำขอดึงข้อมูลเป็น - เป็นคุณลักษณะหรือการแก้ไขข้อบกพร่อง หรือการแก้ไขการทดสอบ หรือ บางสิ่งบางอย่างที่เป็นโครงสร้างพื้นฐาน

การดำเนินการของ GitHub สามารถช่วยเราได้อย่างไร มีการดำเนินการที่ยอดเยี่ยม - Release Drafter ช่วยให้คุณสามารถตั้งค่าเทมเพลตไฟล์บันทึกประจำรุ่นเพื่อตั้งค่าหมวดหมู่ของคำขอดึงและจัดกลุ่มโดยอัตโนมัติในไฟล์บันทึกประจำรุ่น:

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

เทมเพลตตัวอย่างสำหรับการตั้งค่ารายงาน (.github/release-draafter.yml):

name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
  - title: ' New Features'
    labels:
      - 'type:features'
# в эту категорию собираем все PR с меткой type:features

  - title: ' Bugs Fixes'
    labels:
      - 'type:fix'
# аналогично для метки type:fix и т.д.

  - title: ' Documentation'
    labels:
      - 'type:documentation'

  - title: ' Configuration'
    labels:
      - 'type:config'

change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
  ## Changes
  $CHANGES

เพิ่มสคริปต์เพื่อสร้างรุ่นร่าง (.github/workflows/release-draft.yml):

name: "Create draft release"

on:
  push:
    branches:
      - master

jobs:
  update_draft_release:
    runs-on: ubuntu-18.04
    steps:
      - uses: release-drafter/release-drafter@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

คำขอดึงทั้งหมดต่อจากนี้จะถูกรวบรวมไว้ในบันทึกประจำรุ่นโดยอัตโนมัติ - มหัศจรรย์!

คำถามนี้อาจเกิดขึ้น: จะเกิดอะไรขึ้นถ้านักพัฒนาลืมใส่แท็กใน PR? ยังไม่ชัดเจนว่าจะใส่หมวดหมู่ใดและคุณจะต้องจัดการด้วยตนเองอีกครั้งโดยแยก PR แต่ละรายการออกจากกัน เพื่อแก้ไขปัญหานี้ เราสามารถใช้การดำเนินการอื่น - ตัวตรวจสอบป้ายกำกับ - โดยจะตรวจสอบว่ามีแท็กอยู่ในคำขอดึงหรือไม่ หากไม่มีแท็กที่จำเป็น การตรวจสอบจะล้มเหลว และเราจะเห็นข้อความเกี่ยวกับเรื่องนี้ในคำขอดึงของเรา

name: "Verify type labels"

on:
  pull_request:
    types: [opened, labeled, unlabeled, synchronize]

jobs:
  triage:
    runs-on: ubuntu-18.04
    steps:
      - uses: zwaldowski/match-label-action@v2
        with:
          allowed: 'type:fix, type:features, type:documentation, type:tests, type:config'

ตอนนี้คำขอดึงใด ๆ จะต้องทำเครื่องหมายด้วยหนึ่งในแท็ก: type:fix, type:features, type:documentation, type:tests, type:config

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

คำอธิบายประกอบอัตโนมัติของคำขอดึง

เนื่องจากเราได้กล่าวถึงหัวข้อดังกล่าวว่าการทำงานอย่างมีประสิทธิภาพกับคำขอดึงข้อมูล จึงคุ้มค่าที่จะพูดถึงการดำเนินการดังกล่าวในฐานะผู้ติดป้ายกำกับ โดยจะใส่แท็กใน PR ตามไฟล์ที่มีการเปลี่ยนแปลง ตัวอย่างเช่น เราสามารถทำเครื่องหมายเป็น [build] คำขอดึงใดๆ ที่มีการเปลี่ยนแปลงในไดเร็กทอรี .github/workflow.

การเชื่อมต่อนั้นค่อนข้างง่าย:

name: "Auto-assign themes to PR"

on:
  - pull_request

jobs:
  triage:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/labeler@v2
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

นอกจากนี้เรายังต้องการไฟล์ที่อธิบายความสอดคล้องระหว่างไดเร็กทอรีโปรเจ็กต์และหัวข้อคำขอดึง:

theme:build:
  - ".github/**"
  - "pom.xml"
  - ".travis.yml"
  - ".gitignore"
  - "Dockerfile"

theme:code:
  - "src/main/*"

theme:tests:
  - "src/test/*"

theme:documentation:
  - "docs/**"

theme:TRASH:
  - ".idea/**"
  - "target/**"

ฉันไม่ประสบความสำเร็จในการจับคู่การดำเนินการที่จะวางป้ายกำกับในคำขอดึงโดยอัตโนมัติกับการดำเนินการที่ตรวจสอบการมีอยู่ของป้ายกำกับที่ต้องการ Match-label ไม่ต้องการเห็นป้ายกำกับที่บอทเพิ่ม ดูเหมือนง่ายกว่าการเขียนการกระทำของคุณเองที่รวมทั้งสองขั้นตอนเข้าด้วยกัน แต่แม้จะอยู่ในรูปแบบนี้มันก็ค่อนข้างสะดวกในการใช้งานคุณต้องเลือกป้ายกำกับจากรายการเมื่อสร้างคำขอดึง

ถึงเวลาปรับใช้แล้ว

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

ฉันลองใช้ตัวเลือกการปรับใช้หลายตัวเลือกผ่าน GitHub Actions (ผ่าน ssh, ผ่าน scp และใช้ docker-hub) และฉันสามารถพูดได้ว่า เป็นไปได้มากว่าคุณจะพบวิธีอัปโหลดไบนารีไปยังเซิร์ฟเวอร์ ไม่ว่าไปป์ไลน์ของคุณจะคดเคี้ยวแค่ไหนก็ตาม เป็น.

ฉันชอบตัวเลือกในการเก็บโครงสร้างพื้นฐานทั้งหมดไว้ในที่เดียว ดังนั้นเรามาดูวิธีการปรับใช้กับแพ็คเกจ GitHub กันดีกว่า (นี่คือพื้นที่เก็บข้อมูลสำหรับเนื้อหาไบนารี, npm, jar, docker)

สคริปต์สำหรับสร้างอิมเมจนักเทียบท่าและเผยแพร่ในแพ็คเกจ GitHub:

name: Deploy docker image

on:
  push:
    branches:
      - 'master'

jobs:

  build_docker_image:
    runs-on: ubuntu-18.04
    steps:

#     Build JAR:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Package
        run: mvn -B clean compile package -DskipTests

#     Set global environment variables:
      - name: set global env
        id: global_env
        run: |
          echo "::set-output name=IMAGE_NAME::${GITHUB_REPOSITORY#*/}"
          echo "::set-output name=DOCKERHUB_IMAGE_NAME::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY#*/}"

#     Build Docker image:
      - name: Build and tag image
        run: |
          docker build -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:latest" -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:${GITHUB_SHA::8}" .

      - name: Docker login
        run: docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}

#     Publish image to github package repository:
      - name: Publish image
        env:
          IMAGE_NAME: $GITHUB_REPOSITORY
        run: docker push "docker.pkg.github.com/$GITHUB_REPOSITORY/${{ steps.global_env.outputs.IMAGE_NAME }}"

ขั้นแรก เราต้องสร้างไฟล์ JAR ของแอปพลิเคชันของเรา หลังจากนั้นเราจะคำนวณเส้นทางไปยังรีจิสทรีนักเทียบท่า GitHub และชื่อของรูปภาพของเรา มีเคล็ดลับบางประการที่เรายังไม่เคยเจอ:

  • โครงสร้างเช่น: echo “::set-output name=NAME::VALUE” อนุญาตให้คุณตั้งค่าของตัวแปรในขั้นตอนปัจจุบัน เพื่อให้สามารถอ่านได้ในขั้นตอนอื่นๆ ทั้งหมด
  • คุณสามารถรับค่าของตัวแปรที่ตั้งไว้ในขั้นตอนก่อนหน้าได้ผ่านตัวระบุของขั้นตอนนี้: ${{ step.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
  • ตัวแปร GITHUB_REPOSITORY มาตรฐานจะจัดเก็บชื่อของพื้นที่เก็บข้อมูลและเจ้าของ (“เจ้าของ/ชื่อ repo”) ในการตัดทุกอย่างออกจากบรรทัดนี้ ยกเว้นชื่อของพื้นที่เก็บข้อมูล เราจะใช้ไวยากรณ์ bash: ${GITHUB_REPOSITORY#*/}

ต่อไปเราต้องสร้างอิมเมจนักเทียบท่า:

docker build -t "docker.pkg.github.com/antkorwin/github-actions/github-actions:latest"

เข้าสู่ระบบรีจิสทรี:

docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}

และเผยแพร่ภาพไปยัง GitHub Package Repository:

docker push "docker.pkg.github.com/antkorwin/github-actions/github-actions"

เพื่อระบุเวอร์ชันของรูปภาพ เราใช้ตัวเลขตัวแรกจากแฮช SHA ของการคอมมิต - GITHUB_SHA ก็มีความแตกต่างเช่นกัน หากคุณสร้างบิลด์ดังกล่าวไม่เพียงแต่เมื่อรวมเข้ากับมาสเตอร์เท่านั้น แต่ยังเป็นไปตามการสร้างคำขอดึงด้วย ดังนั้น SHA อาจไม่ตรงกับแฮชที่เราเห็นในประวัติคอมไพล์ เนื่องจากการดำเนินการ/การดำเนินการชำระเงินจะสร้างแฮชเฉพาะของตัวเองเพื่อหลีกเลี่ยงการดำเนินการหยุดชะงักใน PR

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

หากทุกอย่างเป็นไปด้วยดี จากนั้นเปิดส่วนแพ็คเกจ (https://github.com/antkorwin/github-actions/packages) ในพื้นที่เก็บข้อมูล คุณจะเห็นอิมเมจนักเทียบท่าใหม่:

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

คุณยังสามารถดูรายการเวอร์ชันของอิมเมจนักเทียบท่าได้อีกด้วย

สิ่งที่เหลืออยู่คือการกำหนดค่าเซิร์ฟเวอร์ของเราให้ทำงานกับรีจิสทรีนี้และเริ่มบริการใหม่ ฉันอาจจะพูดถึงวิธีการทำเช่นนี้ผ่าน systemd อีกครั้ง

การตรวจสอบ

มาดูตัวเลือกง่ายๆ เกี่ยวกับวิธีการตรวจสอบสภาพสำหรับแอปพลิเคชันของเราโดยใช้ GitHub Actions แอปพลิเคชันบูตของเรามีตัวกระตุ้น ดังนั้นเราจึงไม่จำเป็นต้องเขียน API เพื่อตรวจสอบสถานะด้วยซ้ำ เราได้ทำทุกอย่างเพื่อคนขี้เกียจแล้ว คุณเพียงแค่ต้องดึงโฮสต์: SERVER-URL:PORT/actuator/health

$ curl -v 127.0.0.1:8080/actuator/health

> GET /actuator/health HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*

< HTTP/1.1 200
< Content-Type: application/vnd.spring-boot.actuator.v3+json
< Transfer-Encoding: chunked
< Date: Thu, 04 Jun 2020 12:33:37 GMT

{"status":"UP"}

สิ่งที่เราต้องทำคือเขียนงานเพื่อตรวจสอบเซิร์ฟเวอร์โดยใช้ cron และหากจู่ๆ เขาไม่ตอบเรา เราจะส่งการแจ้งเตือนทางโทรเลข

ก่อนอื่น มาดูวิธีรันเวิร์กโฟลว์ cron กัน:

on:
  schedule:
    - cron:  '*/5 * * * *'

มันง่ายมาก ฉันไม่อยากจะเชื่อเลยด้วยซ้ำว่าใน Github คุณสามารถสร้างกิจกรรมที่ไม่เข้ากับ webhook ได้เลย รายละเอียดอยู่ในเอกสารประกอบ: help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule

มาตรวจสอบสถานะเซิร์ฟเวอร์ด้วยตนเองผ่านทาง curl:

jobs:
  ping:
    runs-on: ubuntu-18.04
    steps:

      - name: curl actuator
        id: ping
        run: |
          echo "::set-output name=status::$(curl ${{secrets.SERVER_HOST}}/api/actuator/health)"

      - name: health check
        run: |
          if [[ ${{ steps.ping.outputs.status }} != *"UP"* ]]; then
            echo "health check is failed"
            exit 1
          fi
          echo "It's OK"

ขั้นแรก เราจะบันทึกสิ่งที่เซิร์ฟเวอร์ตอบสนองต่อคำขอลงในตัวแปร ในขั้นตอนถัดไปเราจะตรวจสอบว่าสถานะเป็น UP และหากไม่เป็นเช่นนั้น เราจะออกโดยมีข้อผิดพลาด หากคุณต้องการ "ครอบงำ" การกระทำด้วยมือของคุณแล้วล่ะก็ ทางออก 1 - อาวุธที่เหมาะสม

  - name: send alert in telegram
    if: ${{ failure() }}
    uses: appleboy/telegram-action@master
    with:
      to: ${{ secrets.TELEGRAM_TO }}
      token: ${{ secrets.TELEGRAM_TOKEN }}
      message: |
        Health check of the:
        ${{secrets.SERVER_HOST}}/api/actuator/health
        failed with the result:
        ${{ steps.ping.outputs.status }}

เราส่งไปที่โทรเลขเฉพาะในกรณีที่การดำเนินการล้มเหลวในขั้นตอนก่อนหน้า ในการส่งข้อความ เราใช้ appleboy/telegram-action คุณสามารถอ่านเกี่ยวกับวิธีรับโทเค็นบอทและรหัสแชทได้ในเอกสารประกอบ: github.com/appleboy/telegram-action

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

อย่าลืมเขียนความลับบน Github: URL สำหรับเซิร์ฟเวอร์และโทเค็นสำหรับบอตโทรเลข

โบนัสแทร็ก - JIRA สำหรับคนขี้เกียจ

ฉันสัญญาว่าเราจะกลับไปที่ JIRA และเราก็กลับมาแล้ว หลายร้อยครั้งที่ฉันสังเกตเห็นสถานการณ์ที่ยืนหยัดเมื่อนักพัฒนาสร้างฟีเจอร์ รวมสาขา แต่ลืมลากปัญหาไปที่ JIRA แน่นอนว่าถ้าทั้งหมดนี้ทำในที่เดียวคงง่ายกว่า แต่ในความเป็นจริงเราเขียนโค้ดใน IDE รวมสาขาเข้ากับ bitbucket หรือ GitHub แล้วลากงานไปที่ Jira เพื่อสิ่งนี้เราต้องเปิดหน้าต่างใหม่ บางครั้งเข้าสู่ระบบอีกครั้งและอื่นๆ เมื่อคุณจำได้แม่นว่าต้องทำอะไรต่อไป ก็ไม่มีประโยชน์ที่จะต้องเปิดกระดานอีกครั้ง เป็นผลให้ในตอนเช้าคุณต้องใช้เวลาอัปเดตกระดานงาน

GitHub จะช่วยเราในงานประจำนี้ด้วย สำหรับผู้เริ่มต้น เราสามารถลากปัญหาลงในคอลัมน์ code_review โดยอัตโนมัติเมื่อเราส่งคำขอดึง สิ่งที่คุณต้องทำคือปฏิบัติตามหลักการตั้งชื่อสาขา:

[имя проекта]-[номер таска]-название

ตัวอย่างเช่น หากคีย์โปรเจ็กต์ "GitHub Actions" คือ GA แสดงว่า GA-8-jira-bot อาจเป็นสาขาสำหรับการดำเนินงาน GA-8

การบูรณาการกับ JIRA ทำงานผ่านการกระทำของ Atlassian พวกมันไม่สมบูรณ์แบบ ฉันต้องบอกว่าบางส่วนไม่ได้ผลสำหรับฉันเลย แต่เราจะพูดถึงเฉพาะสิ่งที่ได้ผลและใช้งานจริงเท่านั้น

ขั้นแรก คุณต้องเข้าสู่ระบบ JIRA โดยใช้การดำเนินการ: atlassian/gajira-login

jobs:
  build:
    runs-on: ubuntu-latest
    name: Jira Workflow
    steps:
      - name: Login
        uses: atlassian/gajira-login@master
        env:
          JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
          JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
          JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}

ในการดำเนินการนี้ คุณจะต้องได้รับโทเค็นใน JIRA โดยอธิบายวิธีการดำเนินการไว้ที่นี่: confluence.atlassian.com/cloud/api-tokens-938839638.html

เราแยกตัวระบุงานออกจากชื่อสาขา:

  - name: Find Issue
    id: find_issue
    shell: bash
    run: |
      echo "::set-output name=ISSUE_ID::$(echo ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}')"
      echo brach name: $GITHUB_HEAD_REF
      echo extracted issue: ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}'

  - name: Check Issue
    shell: bash
    run: |
      if [[ "${{steps.find_issue.outputs.ISSUE_ID}}" == "" ]]; then
        echo "Please name your branch according to the JIRA issue: [project_key]-[task_number]-branch_name"
        exit 1
      fi
      echo succcessfully found JIRA issue: ${{steps.find_issue.outputs.ISSUE_ID}}

หากคุณค้นหาในตลาด GitHub คุณจะพบการดำเนินการสำหรับงานนี้ แต่ฉันต้องเขียนสิ่งเดียวกันโดยใช้ grep โดยใช้ชื่อของสาขา เนื่องจากการกระทำจาก Atlassian นี้ไม่ต้องการทำงานกับโครงการของฉัน แต่อย่างใด เพื่อดูว่ามีอะไรผิดปกติ - นานกว่าการทำสิ่งเดียวกันด้วยมือของคุณ

สิ่งที่เหลืออยู่คือการย้ายงานไปที่คอลัมน์ "การตรวจสอบโค้ด" เมื่อสร้างคำขอดึง:

  - name: Transition issue
    if: ${{ success() }}
    uses: atlassian/gajira-transition@master
    with:
      issue: ${{ steps.find_issue.outputs.ISSUE_ID }}
      transition: "Code review"

มีการดำเนินการพิเศษสำหรับสิ่งนี้บน GitHub สิ่งที่คุณต้องมีคือ ID ปัญหาที่ได้รับในขั้นตอนก่อนหน้าและการอนุญาตใน JIRA ที่เราทำข้างต้น

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

ในทำนองเดียวกัน คุณสามารถลากงานเมื่อรวมเข้ากับงานหลัก และกิจกรรมอื่นๆ จากเวิร์กโฟลว์ GitHub โดยทั่วไปแล้ว ทุกอย่างขึ้นอยู่กับจินตนาการและความปรารถนาของคุณที่จะทำให้กระบวนการตามปกติเป็นไปโดยอัตโนมัติ

ผลการวิจัย

หากคุณดูแผนภาพ DEVOPS แบบคลาสสิก เราได้ครอบคลุมทุกขั้นตอนแล้ว ยกเว้นบางทีอาจดำเนินการ ฉันคิดว่าถ้าคุณลอง คุณจะพบการดำเนินการบางอย่างในตลาดเพื่อรวมเข้ากับระบบฝ่ายช่วยเหลือ ดังนั้นเราจะถือว่าไปป์ไลน์เปลี่ยนไป ออกมาอย่างละเอียดและสามารถสรุปผลตามการใช้งานได้

แวดวงนรกด้วย GitHub Actions (การสร้างไปป์ไลน์ CI/CD สำหรับโปรเจ็กต์ Java)

จุดเด่น:

  • ตลาดซื้อขายพร้อมทำทุกโอกาสนี่มันเจ๋งมาก โดยส่วนใหญ่ คุณสามารถดูซอร์สโค้ดเพื่อทำความเข้าใจวิธีแก้ปัญหาที่คล้ายกันหรือโพสต์คำขอคุณสมบัติไปยังผู้เขียนได้โดยตรงในพื้นที่เก็บข้อมูล GitHub
  • การเลือกแพลตฟอร์มเป้าหมายสำหรับการประกอบ: Linux, mac os, windows ถือเป็นคุณสมบัติที่น่าสนใจทีเดียว
  • แพ็คเกจ Github เป็นสิ่งที่ดี สะดวกในการเก็บโครงสร้างพื้นฐานทั้งหมดไว้ในที่เดียว คุณไม่จำเป็นต้องท่องผ่านหน้าต่างต่างๆ ทุกอย่างอยู่ภายในรัศมีการคลิกเมาส์หนึ่งหรือสองครั้ง และผสานรวมเข้ากับ GitHub Actions ได้อย่างสมบูรณ์แบบ การสนับสนุนรีจิสทรีนักเทียบท่าในเวอร์ชันฟรีก็เป็นข้อได้เปรียบที่ดีเช่นกัน
  • GitHub ซ่อนความลับไว้ในบันทึกบิลด์ ดังนั้นการใช้มันเพื่อจัดเก็บรหัสผ่านและโทเค็นจึงไม่น่ากลัวขนาดนั้น ในระหว่างการทดลองทั้งหมดของฉัน ฉันไม่เคยมองเห็นความลับในรูปแบบที่บริสุทธิ์ของมันในคอนโซลเลย
  • ฟรีสำหรับโครงการโอเพ่นซอร์ส

จุดด้อย:

  • YML ฉันไม่ชอบเขา เมื่อทำงานกับโฟลว์ดังกล่าว ข้อความคอมมิตที่พบบ่อยที่สุดที่ฉันมีคือ “แก้ไขรูปแบบ yml” บางครั้งคุณลืมวางแท็บไว้ที่ใดที่หนึ่ง บางครั้งคุณเขียนมันผิดบรรทัด โดยทั่วไปแล้ว การนั่งหน้าจอพร้อมกับไม้โปรแทรกเตอร์และไม้บรรทัดไม่ใช่ประสบการณ์ที่น่าพึงพอใจที่สุด
  • DEBUG การดีบักโฟลว์ด้วยการคอมมิต การรันการสร้างใหม่ และเอาท์พุตไปยังคอนโซลนั้นไม่สะดวกเสมอไป แต่เป็นหมวดหมู่ "คุณทำมากเกินไป" คุณคุ้นเคยกับการทำงานกับ IDEA ที่สะดวกสบาย เมื่อคุณสามารถดีบักอะไรก็ได้ .
  • คุณสามารถเขียนการกระทำของคุณกับอะไรก็ได้หากคุณรวมไว้ใน Docker แต่รองรับเฉพาะจาวาสคริปต์เท่านั้น แน่นอนว่านี่เป็นเรื่องของรสนิยม แต่ฉันชอบอย่างอื่นแทน js

ฉันขอเตือนคุณว่าพื้นที่เก็บข้อมูลพร้อมสคริปต์ทั้งหมดอยู่ที่นี่: github.com/antkorwin/github-actions

สัปดาห์หน้าผมจะได้แสดงด้วย รายงาน ในการประชุม Heisenbug 2020 Piter ฉันจะบอกคุณไม่เพียงแต่วิธีการหลีกเลี่ยงข้อผิดพลาดในการเตรียมข้อมูลทดสอบ แต่ยังแบ่งปันความลับของฉันในการทำงานกับชุดข้อมูลในแอปพลิเคชัน Java!

ที่มา: will.com