ProHoster > Blog > Pentadbiran > Bulatan neraka dengan Tindakan GitHub (membina saluran paip CI/CD untuk projek Java)
Bulatan neraka dengan Tindakan GitHub (membina saluran paip CI/CD untuk projek Java)
Saya sering perlu membina saluran paip untuk membina projek di Jawa. Kadang-kadang ia sumber terbuka, kadang-kadang tidak. Saya baru-baru ini memutuskan untuk cuba mengalihkan beberapa repositori saya dari Travis-CI dan TeamCity ke Tindakan GitHub, dan inilah yang terhasil daripadanya.
Apa yang akan kami automasi?
Mula-mula, kami memerlukan projek yang akan kami automasi, mari buat aplikasi kecil dalam boot Spring / Java 11 / Maven. Untuk tujuan artikel ini, kami tidak akan berminat dengan logik aplikasi sama sekali; infrastruktur di sekeliling aplikasi adalah penting kepada kami, jadi pengawal API REST yang mudah akan mencukupi untuk kami.
Anda boleh melihat sumber di sini: github.com/antkorwin/github-actions Semua peringkat membina saluran paip dicerminkan dalam permintaan tarik untuk projek ini.
JIRA dan perancangan
Perlu dikatakan bahawa kami biasanya menggunakan JIRA sebagai penjejak isu, jadi mari kita buat papan berasingan untuk projek ini dan tambahkan isu pertama di sana:
Tidak lama kemudian, kami akan kembali kepada perkara menarik yang boleh ditawarkan oleh JIRA dan GitHub secara gabungan.
Kami mengautomasikan pemasangan projek
Projek ujian kami dibina melalui maven, jadi membinanya agak mudah, yang kami perlukan ialah pakej bersih mvn.
Untuk melakukan ini menggunakan Tindakan Github, kita perlu membuat fail dalam repositori yang menerangkan aliran kerja kita, ini boleh dilakukan dengan fail yml biasa, saya tidak boleh mengatakan bahawa saya suka "pengaturcaraan yml", tetapi apa yang boleh kita lakukan - kami melakukannya dalam aliran kerja direktori .github// fail build.yml di mana kami akan menerangkan tindakan semasa membina cawangan induk:
on β ini ialah perihalan acara di mana skrip kami akan dilancarkan.
pada: tarik_permintaan/tolak β menunjukkan bahawa aliran kerja ini perlu dilancarkan setiap kali tolakan dibuat kepada induk dan permintaan tarik dibuat.
Berikut ialah penerangan tentang tugasan (pekerjaan) dan langkah pelaksanaan (langkah-langkah) untuk setiap tugasan.
berjalan-on - di sini kita boleh memilih OS sasaran, secara mengejutkan, anda juga boleh memilih Mac OS, tetapi pada repositori peribadi ini agak mahal (berbanding dengan Linux).
menggunakan membolehkan anda menggunakan semula tindakan lain, contohnya, menggunakan tindakan tindakan/setup-java yang kami pasangkan persekitaran untuk Java 11.
Dengan cara bersama kita boleh menentukan parameter yang kita gunakan untuk melancarkan tindakan, pada asasnya ini adalah hujah yang akan dihantar kepada tindakan.
Yang tinggal hanyalah menjalankan pembinaan projek di Maven: run: mvn -B clean package bendera -B mengatakan bahawa kami memerlukan mod bukan interaktif supaya ahli sihir tiba-tiba tidak mahu bertanya sesuatu kepada kami
Hebat! Sekarang, setiap kali anda komited kepada tuan, pembinaan projek bermula.
Mengautomasikan pelancaran ujian
Perhimpunan adalah baik, tetapi pada hakikatnya, projek boleh dipasang dengan selamat, tetapi tidak berfungsi. Oleh itu, langkah seterusnya ialah mengautomasikan larian ujian. Di samping itu, agak mudah untuk melihat keputusan lulus ujian apabila anda melakukan semakan PR - anda pasti tahu bahawa ujian itu lulus dan tiada siapa yang terlupa untuk menjalankan cawangan mereka sebelum melakukan gabungan.
Kami akan menjalankan ujian apabila membuat permintaan tarik dan bergabung ke dalam induk, dan pada masa yang sama kami akan menambah penciptaan laporan mengenai liputan kod.
Untuk menampung ujian, saya menggunakan codecov bersama-sama dengan pemalam jacoco. codecov mempunyai tindakannya sendiri, tetapi ia memerlukan token untuk berfungsi dengan permintaan tarik kami:
${{ secrets.CODECOV_TOKEN }} β kita akan melihat pembinaan ini lebih daripada sekali, rahsia ialah mekanisme untuk menyimpan rahsia dalam GitHub, kita boleh menulis di sana kata laluan/token/hos/url dan data lain yang tidak sepatutnya dimasukkan dalam pangkalan kod repositori.
Anda boleh menambah pembolehubah pada rahsia dalam tetapan repositori di GitHub:
Anda boleh mendapatkan token di codecov.io Selepas kebenaran melalui GitHub, untuk menambah projek awam anda hanya perlu mengikuti pautan seperti ini: Nama pengguna GitHub/[nama Repo]. Repositori peribadi juga boleh ditambah; untuk melakukan ini, anda perlu memberikan hak codecov kepada aplikasi dalam Github.
Kini bot codecov akan memasukkan setiap permintaan tarik kami dan menambah graf perubahan liputan:
Mari tambahkan penganalisis statik
Dalam kebanyakan projek sumber terbuka saya, saya menggunakan awan sonar untuk analisis kod statik, ia agak mudah untuk disambungkan ke travis-ci. Jadi ini adalah langkah logik apabila berhijrah ke GitHub Actions untuk melakukan perkara yang sama. Pasaran tindakan adalah perkara yang menarik, tetapi kali ini ia mengecewakan saya sedikit, kerana di luar kebiasaan saya menemui tindakan yang saya perlukan dan menambahkannya pada aliran kerja. Tetapi ternyata sonar tidak menyokong kerja melalui tindakan untuk menganalisis projek pada maven atau gradle. Sudah tentu, ini ditulis dalam dokumentasi, tetapi siapa yang membacanya?!
Ia tidak boleh dilakukan melalui tindakan, jadi kami akan melakukannya melalui pemalam mvn:
SONAR_TOKEN - boleh didapati di sonarcloud.io dan anda perlu mendaftarkannya secara rahsia. GITHUB_TOKEN - ini ialah token terbina dalam yang GitHub jana, dengan bantuan sonarcloud[bot] akan dapat log masuk ke Git untuk meninggalkan mesej kepada kami dalam permintaan tarik.
Dsonar.projectKey β nama projek dalam sonar, anda boleh melihatnya dalam tetapan projek.
Dsonar.organisasi β nama organisasi daripada GitHub.
Kami membuat permintaan tarik dan menunggu sonarcloud[bot] datang dalam ulasan:
Pengurusan pelepasan
Binaan telah dikonfigurasikan, ujian telah dijalankan dan kami boleh membuat keluaran. Mari lihat bagaimana Tindakan GitHub boleh menjadikan pengurusan keluaran lebih mudah.
Di tempat kerja, saya mempunyai projek yang asas kodnya dalam bitbucket (semuanya seperti dalam cerita itu "Saya menulis ke bitbucket pada siang hari, komited dengan GitHub pada waktu malam"). Malangnya, bitbucket tidak mempunyai alat pengurusan keluaran terbina dalam. Ini adalah masalah, kerana untuk setiap keluaran anda perlu membuat halaman secara manual dalam pertemuan dan membuang semua ciri yang disertakan dalam keluaran di sana, mencari melalui istana minda, tugas dalam jira, melakukan dalam repositori. Terdapat banyak peluang untuk melakukan kesilapan, anda boleh melupakan sesuatu atau memasukkan sesuatu yang telah dikeluarkan kali terakhir, kadangkala tidak jelas untuk mengklasifikasikan permintaan tarik sebagai - adakah ia ciri atau pembetulan pepijat, atau ujian pengeditan, atau sesuatu infrastruktur.
Bagaimanakah tindakan GitHub boleh membantu kami? Terdapat tindakan yang hebat - penggubal keluaran, ia membolehkan anda menetapkan templat fail nota keluaran untuk menyediakan kategori permintaan tarik dan mengumpulkannya secara automatik dalam fail nota keluaran:
Contoh templat untuk menyediakan laporan (.github/release-drafter.yml):
Semua permintaan tarik mulai sekarang akan dikumpulkan dalam nota keluaran secara automatik - ajaib!
Di sini persoalan mungkin timbul: bagaimana jika pemaju terlupa untuk meletakkan tag dalam PR? Kemudian tidak jelas kategori mana untuk memasukkannya, dan sekali lagi anda perlu menanganinya secara manual, dengan setiap PR secara berasingan. Untuk menyelesaikan masalah ini, kami boleh menggunakan tindakan lain - pengesah label - ia menyemak kehadiran teg pada permintaan tarik. Jika tiada teg yang diperlukan, maka semakan akan gagal dan kami akan melihat mesej tentang perkara ini dalam permintaan tarik kami.
Sekarang sebarang permintaan tarik mesti ditandakan dengan salah satu teg: type:fix, type:features, type:documentation, type:tests, type:config.
Autoanotasi permintaan tarik
Memandangkan kami menyentuh topik seperti kerja yang berkesan dengan permintaan tarik, patut dibincangkan tentang tindakan seperti pelabel, ia meletakkan tag dalam PR berdasarkan fail yang telah diubah. Sebagai contoh, kita boleh menandai sebagai [membina] sebarang permintaan tarik yang mengandungi perubahan pada direktori .github/workflow.
Saya tidak berjaya memasangkan tindakan yang meletakkan label secara automatik dalam permintaan tarik dengan tindakan yang menyemak kehadiran label yang diperlukan; label padanan tidak mahu melihat label yang ditambahkan oleh bot. Nampaknya lebih mudah untuk menulis tindakan anda sendiri yang menggabungkan kedua-dua peringkat. Tetapi walaupun dalam bentuk ini ia agak mudah digunakan; anda perlu memilih label daripada senarai semasa membuat permintaan tarik.
Sudah tiba masanya untuk digunakan
Saya mencuba beberapa pilihan penempatan melalui Tindakan GitHub (melalui ssh, melalui scp, dan menggunakan docker-hub), dan saya boleh mengatakan bahawa, kemungkinan besar, anda akan menemui cara untuk memuat naik binari ke pelayan, tidak kira betapa bengkok saluran paip anda ialah.
Saya suka pilihan untuk menyimpan keseluruhan infrastruktur di satu tempat, jadi mari lihat cara untuk menggunakan Pakej GitHub (ini adalah repositori untuk kandungan binari, npm, jar, docker).
Skrip untuk membina imej docker dan menerbitkannya dalam Pakej GitHub:
Pertama, kami perlu membina fail JAR aplikasi kami, selepas itu kami mengira laluan ke pendaftaran docker GitHub dan nama imej kami. Terdapat beberapa helah di sini yang belum kami temui lagi:
pembinaan seperti: echo β::set-output name=NAME::VALUEβ membolehkan anda menetapkan nilai pembolehubah dalam langkah semasa, supaya ia kemudiannya boleh dibaca dalam semua langkah lain.
anda boleh mendapatkan nilai set pembolehubah dalam langkah sebelumnya melalui pengecam langkah ini: ${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
Pembolehubah standard GITHUB_REPOSITORY menyimpan nama repositori dan pemiliknya ("pemilik/nama-repo"). Untuk memotong segala-galanya daripada baris ini kecuali nama repositori, kami akan menggunakan sintaks bash: ${GITHUB_REPOSITORY#*/}
Untuk menunjukkan versi imej, kami menggunakan digit pertama dari hash SHA komit - GITHUB_SHA terdapat juga nuansa di sini, jika anda membuat binaan sedemikian bukan sahaja apabila bergabung menjadi induk, tetapi juga mengikut penciptaan permintaan tarik acara, maka SHA mungkin tidak sepadan dengan cincang yang kita lihat dalam sejarah git, kerana tindakan/tindakan checkout membuat cincangan uniknya sendiri untuk mengelakkan tindakan buntu dalam PR.
Jika semuanya berfungsi dengan baik, kemudian membuka bahagian pakej (https://github.com/antkorwin/github-actions/packages) dalam repositori, anda akan melihat imej docker baharu:
Di sana anda juga boleh melihat senarai versi imej docker.
Apa yang tinggal ialah mengkonfigurasi pelayan kami untuk berfungsi dengan pendaftaran ini dan memulakan semula perkhidmatan. Saya mungkin akan bercakap tentang cara melakukan ini melalui systemd lain kali.
Pemantauan
Mari lihat pilihan mudah tentang cara melakukan pemeriksaan kesihatan untuk aplikasi kami menggunakan Tindakan GitHub. Aplikasi but kami mempunyai penggerak, jadi kami tidak perlu menulis API untuk menyemak statusnya; kami telah melakukan segala-galanya untuk mereka yang malas. Anda hanya perlu menarik hos: SERVER-URL:PORT/actuator/health
Apa yang kami perlukan ialah menulis tugas untuk menyemak pelayan menggunakan cron, dan jika tiba-tiba ia tidak menjawab kami, maka kami akan menghantar pemberitahuan melalui telegram.
Mula-mula, mari kita fikirkan cara menjalankan aliran kerja cron:
Mari semak status pelayan secara manual melalui 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"
Mula-mula, kami menyimpan ke dalam pembolehubah apa yang pelayan menjawab permintaan itu, dalam langkah seterusnya kami menyemak bahawa statusnya UP dan, jika ini tidak berlaku, maka kami keluar dengan ralat. Jika anda perlu "mengatasi" tindakan dengan tangan anda, maka jalan keluar 1 - senjata yang sesuai.
- 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 }}
Kami menghantar ke telegram hanya jika tindakan gagal pada langkah sebelumnya. Untuk menghantar mesej, kami menggunakan appleboy/telegram-action; anda boleh membaca tentang cara mendapatkan token bot dan id sembang dalam dokumentasi: github.com/appleboy/telegram-action
Jangan lupa untuk menulis dalam rahsia di Github: URL untuk pelayan dan token untuk bot telegram.
Lagu bonus - JIRA untuk yang malas
Saya berjanji bahawa kami akan kembali ke JIRA, dan kami telah kembali. Beratus-ratus kali saya telah memerhatikan situasi pada pendirian apabila pembangun membuat ciri, menggabungkan cawangan, tetapi terlupa untuk menyeret isu itu ke JIRA. Sudah tentu, jika semua ini dilakukan di satu tempat, ia akan menjadi lebih mudah, tetapi sebenarnya kita menulis kod dalam IDE, menggabungkan cawangan ke bitbucket atau GitHub, dan kemudian seret tugas ke Jira, untuk ini kita perlu membuka tingkap baharu , kadangkala log masuk semula dan lain-lain. Apabila anda mengingati dengan sempurna apa yang perlu anda lakukan seterusnya, maka tidak ada gunanya membuka papan semula. Akibatnya, pada waktu pagi pada standup anda perlu meluangkan masa mengemas kini papan tugas.
GitHub juga akan membantu kami dalam tugas rutin ini; sebagai permulaan, kami boleh menyeret isu secara automatik ke dalam lajur code_review apabila kami menyerahkan permintaan tarik. Apa yang anda perlu lakukan ialah mengikuti konvensyen penamaan cawangan:
contohnya, jika kunci projek "Tindakan GitHub" ialah GA, maka GA-8-jira-bot boleh menjadi cawangan untuk melaksanakan tugas GA-8.
Integrasi dengan JIRA berfungsi melalui tindakan dari Atlassian, mereka tidak sempurna, saya mesti mengatakan bahawa sesetengah daripada mereka tidak berfungsi untuk saya sama sekali. Tetapi kami akan membincangkan hanya yang pasti berfungsi dan digunakan secara aktif.
Mula-mula anda perlu log masuk ke JIRA menggunakan tindakan: atlassian/gajira-login
Kami mengekstrak pengecam tugas daripada nama cawangan:
- 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}}
Jika anda mencari dalam pasaran GitHub, anda boleh mencari tindakan untuk tugas ini, tetapi saya terpaksa menulis perkara yang sama menggunakan grep menggunakan nama cawangan, kerana tindakan dari Atlassian ini tidak mahu bekerja pada projek saya dalam apa cara sekalipun , untuk mengetahui apa yang salah di sana - lebih lama daripada melakukan perkara yang sama dengan tangan anda.
Yang tinggal hanyalah mengalihkan tugas ke lajur "Semakan kod" semasa membuat permintaan tarik:
Terdapat tindakan khas untuk ini di GitHub, yang diperlukan hanyalah ID isu yang diperoleh pada langkah sebelumnya dan kebenaran dalam JIRA yang kami lakukan di atas.
Dengan cara yang sama, anda boleh menyeret tugas apabila bergabung ke dalam induk dan acara lain daripada aliran kerja GitHub. Secara umum, semuanya bergantung pada imaginasi dan keinginan anda untuk mengautomasikan proses rutin.
Penemuan
Jika anda melihat gambarajah DEVOPS klasik, kami telah merangkumi semua peringkat, kecuali mungkin beroperasi, saya fikir jika anda mencuba, anda boleh menemui beberapa tindakan di pasaran untuk penyepaduan dengan sistem meja bantuan, jadi kami akan menganggap bahawa saluran paip bertukar teliti dan kesimpulan boleh dibuat berdasarkan penggunaannya.
Kelebihan:
Pasaran dengan tindakan sedia untuk semua majlis, ini sangat hebat. Dalam kebanyakannya, anda juga boleh melihat kod sumber untuk memahami cara menyelesaikan masalah yang sama atau menyiarkan permintaan ciri kepada pengarang terus dalam repositori GitHub.
Memilih platform sasaran untuk pemasangan: Linux, mac os, windows adalah ciri yang agak menarik.
Pakej Github adalah perkara yang hebat, ia mudah untuk menyimpan keseluruhan infrastruktur di satu tempat, anda tidak perlu melayari tetingkap yang berbeza, semuanya berada dalam radius satu atau dua klik tetikus dan disepadukan dengan sempurna dengan Tindakan GitHub. Sokongan pendaftaran Docker dalam versi percuma juga merupakan kelebihan yang baik.
GitHub menyembunyikan rahsia dalam log binaan, jadi menggunakannya untuk menyimpan kata laluan dan token tidaklah begitu menakutkan. Semasa semua eksperimen saya, saya tidak pernah dapat melihat rahsia dalam bentuk tulennya dalam konsol.
Percuma untuk projek Sumber Terbuka
Cons:
YML, saya tidak suka dia. Apabila bekerja dengan aliran sedemikian, mesej komit yang paling biasa saya miliki ialah "betulkan format yml", kadangkala anda terlupa meletakkan tab di suatu tempat, kadangkala anda menulisnya pada baris yang salah. Secara umum, duduk di hadapan skrin dengan protraktor dan pembaris bukanlah pengalaman yang paling menyenangkan.
DEBUG, menyahpepijat aliran dengan komit, menjalankan bina semula dan mengeluarkan ke konsol tidak selalunya mudah, tetapi ia lebih kepada kategori "anda keterlaluan"; anda sudah biasa bekerja dengan IDEA yang mudah, apabila anda boleh nyahpepijat apa-apa sahaja .
Anda boleh menulis tindakan anda pada apa-apa sahaja jika anda membungkusnya dalam Docker, tetapi hanya javascript yang disokong secara asli, sudah tentu ini adalah soal rasa, tetapi saya lebih suka sesuatu yang lain daripada js.
Minggu depan saya akan membuat persembahan bersama laporan di persidangan Heisenbug 2020 Piter. Saya akan memberitahu anda bukan sahaja cara untuk mengelakkan kesilapan semasa menyediakan data ujian, tetapi juga berkongsi rahsia saya bekerja dengan set data dalam aplikasi Java!