GitHub Eylemlerini Kullanarak Sürekli Entegrasyon Testi İş Akışı Oluşturma
Yayınlanan: 2022-03-10GitHub ve Bitbucket gibi sürüm kontrol platformlarındaki projelere katkıda bulunurken, genel kural, işlevsel kod tabanını içeren ana dalın olmasıdır. Ardından, birkaç geliştiricinin yeni bir özellik eklemek, bir hatayı düzeltmek vb. için ana öğenin kopyaları üzerinde çalışabileceği başka dallar da vardır. Çok mantıklı çünkü gelen değişikliklerin mevcut kod üzerinde ne tür bir etki yaratacağını izlemek daha kolay hale geliyor. Herhangi bir hata varsa, değişiklikleri ana şubeye entegre etmeden önce kolayca izlenebilir ve düzeltilebilir. Küçük bir proje için bile, hataları veya hataları manuel olarak aramak için her bir kod satırından geçmek zaman alabilir. Sürekli entegrasyonun devreye girdiği yer burasıdır.
Sürekli Entegrasyon (CI) Nedir?
“Sürekli entegrasyon (CI), birden çok katkıda bulunanlardan gelen kod değişikliklerinin tek bir yazılım projesine entegrasyonunu otomatikleştirme uygulamasıdır.”
— Atlassian.com
Sürekli entegrasyonun (CI) arkasındaki genel fikir, projede yapılan değişikliklerin "yapıyı bozmamasını", yani mevcut kod tabanını bozmamasını sağlamaktır. İş akışınızı nasıl kurduğunuza bağlı olarak projenizde sürekli entegrasyon uygulamak, biri havuzda değişiklik yaptığında bir yapı oluşturur.
Peki Yapı Nedir?
Bu bağlamda derleme, kaynak kodun yürütülebilir bir biçimde derlenmesidir. Başarılı olursa, gelen değişikliklerin kod tabanını olumsuz etkilemeyeceği ve kullanıma hazır oldukları anlamına gelir. Ancak, derleme başarısız olursa, değişikliklerin yeniden değerlendirilmesi gerekecektir. Bu nedenle, ana kod tabanına dahil etmeden önce projenin bir kopyası üzerinde farklı bir dalda çalışarak bir projede değişiklik yapılması tavsiye edilir. Bu şekilde, derleme bozulursa, hatanın nereden geldiğini anlamak daha kolay olur ve ana kaynak kodunuzu da etkilemez.
"Kusurları ne kadar erken yakalarsanız, düzeltmeleri o kadar ucuz olur."
— David Farley, Sürekli Teslimat: Oluşturma, Test Etme ve Dağıtım Otomasyonu ile Güvenilir Yazılım Sürümleri
Projeniz için sürekli entegrasyon oluşturmaya yardımcı olacak çeşitli araçlar vardır. Bunlara Jenkins, TravisCI, CircleCI, GitLab CI, GitHub Actions vb. dahildir. Bu eğitim için GitHub Actions'ı kullanacağım.
Sürekli Entegrasyon İçin GitHub Eylemleri
CI Eylemleri, GitHub'da oldukça yeni bir özelliktir ve projenizin derlemesini ve testlerini otomatik olarak çalıştıran iş akışlarının oluşturulmasını sağlar. Bir iş akışı, bir olay meydana geldiğinde etkinleştirilebilecek bir veya daha fazla işi içerir. Bu olay, depodaki dallardan herhangi birine bir itme veya bir çekme talebinin oluşturulması olabilir. Devam ederken bu terimleri ayrıntılı olarak açıklayacağım.
Başlayalım!
Önkoşullar
Bu yeni başlayanlar için bir eğitimdir, bu yüzden çoğunlukla GitHub Actions CI hakkında yüzey seviyesinde konuşacağım. Okuyucular, PostgreSQL veritabanı, Sequelize ORM kullanarak bir Node JS REST API oluşturmaya ve Mocha ve Chai ile testler yazmaya zaten aşina olmalıdır.
Ayrıca makinenizde aşağıdakilerin kurulu olması gerekir:
- düğümJS,
- PostgreSQL,
- NPM,
- VSCode (veya seçtiğiniz herhangi bir düzenleyici ve terminal).
Daha önce oluşturduğum countries-info-api
adlı bir REST API'sini kullanacağım. Rol tabanlı yetkileri olmayan basit bir API'dir (bu öğreticiyi yazarken olduğu gibi). Bu, herkesin bir ülkenin ayrıntılarını ekleyebileceği, sebileceği ve/veya güncelleyebileceği anlamına gelir. Her ülkenin bir kimliği (otomatik oluşturulan UUID), adı, sermayesi ve nüfusu olacaktır. Bunu başarmak için veritabanı için Node js, express js çerçevesi ve Postgresql kullandım.
Test kapsamı için testleri ve sürekli entegrasyon için iş akışı dosyasını yazmaya başlamadan önce sunucuyu, veritabanını nasıl kurduğumu kısaca anlatacağım.
countries-info-api
deposunu takip etmek veya kendi API'nizi oluşturmak için klonlayabilirsiniz.
Kullanılan teknoloji : Node Js, NPM (Javascript için bir paket yöneticisi), Postgresql veritabanı, sequelize ORM, Babel.
Sunucuyu Kurma
Sunucuyu kurmadan önce npm'den bazı bağımlılıklar kurdum.
npm install express dotenv cors npm install --save-dev @babel/core @babel/cli @babel/preset-env nodemon
Ekspres çerçeveyi kullanıyorum ve ES6 formatında yazıyorum, bu yüzden kodumu derlemek için Babeljs'e ihtiyacım olacak. Nasıl çalıştığı ve projeniz için nasıl yapılandırılacağı hakkında daha fazla bilgi edinmek için resmi belgeleri okuyabilirsiniz. Nodemon, kodda yapılan değişiklikleri algılayacak ve sunucuyu otomatik olarak yeniden başlatacaktır.
Not : --save --save-dev
bayrağı kullanılarak kurulan Npm paketleri yalnızca geliştirme aşamalarında gereklidir ve package.json
dosyasındaki devDependencies altında görülür.
Aşağıdakileri index.js
ekledim:
import express from "express"; import bodyParser from "body-parser"; import cors from "cors"; import "dotenv/config"; const app = express(); const port = process.env.PORT; app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(cors()); app.get("/", (req, res) => { res.send({message: "Welcome to the homepage!"}) }) app.listen(port, () => { console.log(`Server is running on ${port}...`) })
Bu, .env
dosyasındaki PORT
değişkenine atanan her şey üzerinde çalışacak şekilde ayarlar. Burası aynı zamanda başkalarının kolayca erişmesini istemediğimiz değişkenleri bildireceğimiz yerdir. dotenv
npm paketi, ortam değişkenlerimizi .env
yükler.
Şimdi terminalimde npm run start
alıyorum:

Gördüğünüz gibi sunucumuz aktif ve çalışıyor. Yaşasın!
Bu bağlantı https://127.0.0.1:your_port_number/
web tarayıcınızdaki karşılama mesajını döndürmelidir. Yani, sunucu çalıştığı sürece.

Sıradaki, Veritabanı ve Modeller.
Ülke modelini Sequelize kullanarak oluşturdum ve Postgres veri tabanıma bağlandım. Sequelize, Nodejs için bir ORM'dir. En büyük avantajı, bize ham SQL sorguları yazmak için zaman kazandırmasıdır.
Postgresql kullandığımız için veritabanı, CREATE DATABASE database_name
komutu kullanılarak psql komut satırı üzerinden oluşturulabilir. Bu, terminalinizde de yapılabilir, ancak ben PSQL Shell'i tercih ederim.
env dosyasında aşağıdaki formatı takip ederek veritabanımızın bağlantı dizisini oluşturacağız.
TEST_DATABASE_URL = postgres://<db_username>:<db_password>@127.0.0.1:5432/<database_name>
Modelim için bu devam dersi öğreticisini takip ettim. Takip etmesi kolaydır ve Sequelize kurulumuyla ilgili her şeyi açıklar.
Daha sonra yeni oluşturduğum model için testler yazacağım ve Coverall'da kapsamı ayarlayacağım.
Test Yazma ve Raporlama Kapsamı
Testler neden yazılır? Şahsen, test yazmanın bir geliştirici olarak yazılımınızın kullanıcılarınızın elinde nasıl performans göstermesinin beklendiğini daha iyi anlamanıza yardımcı olduğuna inanıyorum çünkü bu bir beyin fırtınası sürecidir. Ayrıca hataları zamanında keşfetmenize yardımcı olur.
testler:
Farklı yazılım test yöntemleri vardır, ancak bu eğitim için birim ve uçtan uca testten yararlandım.
Testlerimi Mocha test çerçevesini ve Chai onaylama kitaplığını kullanarak yazdım. sequelize.define kullanarak oluşturduğum modeli test etmeye yardımcı olması için sequelize-test-helpers
da sequelize.define
.

Test kapsamı:
Test kapsamınızı kontrol etmeniz önerilir çünkü sonuç, test senaryolarımızın gerçekten kodu kapsayıp kapsamadığını ve ayrıca test senaryolarımızı çalıştırdığımızda ne kadar kod kullanıldığını gösterir.
İstanbul (bir test kapsamı aracı), nyc (Instabul'un CLI istemcisi) ve Tulumları kullandım.
Dokümanlara göre İstanbul, ES5 ve ES2015+ JavaScript kodunuzu satır sayaçlarıyla ölçer, böylece birim testlerinizin kod tabanınızı ne kadar iyi kullandığını takip edebilirsiniz.
package.json
, test komut dosyası testleri çalıştırır ve bir rapor oluşturur.
{ "scripts": { "test": "nyc --reporter=lcov --reporter=text mocha -r @babel/register ./src/test/index.js" } }
Bu süreçte, ham kapsam bilgilerini içeren bir .nyc_output
klasörü ve kapsam raporu dosyalarını içeren bir coverage
klasörü oluşturacaktır. Her iki dosya da depomda gerekli değil, bu yüzden onları .gitignore
dosyasına yerleştirdim.
Artık bir rapor oluşturduğumuza göre, onu Coveralls'a göndermemiz gerekiyor. Tulumlar (ve diğer kapsama araçları, sanırım) ile ilgili harika bir şey, test kapsamınızı nasıl bildirdiğidir. Kapsam dosya bazında bölünmüştür ve ilgili kapsamı, kapsanan ve kaçırılan satırları ve yapı kapsamında nelerin değiştiğini görebilirsiniz.
Başlamak için tulumlar npm paketini kurun. Ayrıca tulumlara giriş yapmanız ve repoyu buna eklemeniz gerekir.

Ardından, kök dizininizde bir coveralls.yml
dosyası oluşturarak javascript projeniz için tulumları ayarlayın. Bu dosya, tulumlardaki deponuz için ayarlar bölümünden alınan repo-token
tutacaktır.
package.json dosyasında ihtiyaç duyulan bir diğer komut dosyası, kapsam komut dosyalarıdır. Bu komut dosyası, Eylemler aracılığıyla bir yapı oluştururken kullanışlı olacaktır.
{ "scripts": { "coverage": "nyc npm run test && nyc report --reporter=text-lcov --reporter=lcov | node ./node_modules/coveralls/bin/coveralls.js --verbose" } }
Temel olarak testleri yapacak, raporu alacak ve analiz için tulumlara gönderecek.
Şimdi bu öğreticinin ana noktasına.
Node JS İş Akışı Dosyası Oluşturun
Bu noktada GitHub Action'ımızda çalıştıracağımız gerekli işleri kurduk. ("İşlerin" ne anlama geldiğini merak mı ediyorsunuz? Okumaya devam edin.)
GitHub, bir başlangıç şablonu sağlayarak iş akışı dosyasını oluşturmayı kolaylaştırdı. Eylemler sayfasında görüldüğü gibi, farklı amaçlara hizmet eden birkaç iş akışı şablonu vardır. Bu eğitim için Node.js iş akışını kullanacağız (GitHub'ın zaten nazikçe önerdiği).

Dosyayı doğrudan GitHub'da düzenleyebilirsiniz, ancak dosyayı yerel depomda manuel olarak oluşturacağım. node.js.yml
dosyasını içeren .github/workflows
klasörü kök dizinde olacaktır.
Bu dosya zaten bazı temel komutları içeriyor ve ilk yorum ne yaptıklarını açıklıyor.
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
Üzerinde bazı değişiklikler yapacağım, böylece yukarıdaki yoruma ek olarak kapsama alanı da olacak.
.node.js.yml
:
name: NodeJS CI on: ["push"] jobs: build: name: Build runs-on: windows-latest strategy: matrix: node-version: [12.x, 14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: npm install - run: npm run build --if-present - run: npm run coverage - name: Coveralls uses: coverallsapp/github-action@master env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} COVERALLS_GIT_BRANCH: ${{ github.ref }} with: github-token: ${{ secrets.GITHUB_TOKEN }}
Ne anlama geliyor?
Hadi parçalayalım.
-
name
Bu, iş akışınızın (NodeJS CI) veya işinizin (derleme) adı olur ve GitHub bunu deponuzun eylemler sayfasında görüntüler. -
on
Bu, iş akışını tetikleyen olaydır. Dosyamdaki bu satır, temelde GitHub'a depoma bir push yapıldığında iş akışını tetiklemesini söylüyor. -
jobs
Bir iş akışı, en az bir veya daha fazla iş içerebilir ve her iş, çalıştırma ile belirtilen bir ortamdaruns-on
. Yukarıdaki dosya örneğinde, derlemeyi çalıştıran ve aynı zamanda kapsamı da çalıştıran tek bir iş vardır ve bir windows ortamında çalışır. Ayrıca bunu şu şekilde iki farklı işe ayırabilirim:
Güncellenmiş Node.yml dosyası
name: NodeJS CI on: [push] jobs: build: name: Build runs-on: windows-latest strategy: matrix: node-version: [12.x, 14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: npm install - run: npm run build --if-present - run: npm run test coverage: name: Coveralls runs-on: windows-latest strategy: matrix: node-version: [12.x, 14.x] steps: - uses: coverallsapp/github-action@master env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} with: github-token: ${{ secrets.GITHUB_TOKEN }}
-
env
Bu, iş akışındaki tüm veya belirli işler ve adımlar için kullanılabilen ortam değişkenlerini içerir. Kapsama işinde ortam değişkenlerinin “gizlendiğini” görebilirsiniz. Repo'nuzun sırlar sayfasında ayarlar altında bulunabilirler. -
steps
Bu, temel olarak, o işi çalıştırırken atılması gereken adımların bir listesidir. -
build
işi birkaç şey yapar:- İş akışınız tarafından erişilebilir olması için deponuzu tam anlamıyla kontrol eden bir kontrol eylemi (v2 sürümü belirtir) kullanır;
- Kullanılacak düğüm ortamını ayarlayan bir kurulum düğümü eylemi kullanır;
- package.json dosyamızda bulunan kurulum, derleme ve test komut dosyalarını çalıştırır.
-
coverage
Bu, test paketinizin LCOV kapsama verilerini analiz için coveralls.io'ya gönderen bir tulum uygulaması eylemi kullanır.

Başlangıçta feat-add-controllers-and-route
dalımı zorladım ve Coveralls'dan repo_token dosyasını .coveralls.yml
dosyama eklemeyi unuttum, bu yüzden 132. satırda görebileceğiniz hatayı aldım.

Bad response: 422 {"message":"Couldn't find a repository matching this job.","error":true}
repo_token
ekledikten sonra derlemem başarıyla çalışabildi. Bu belirteç olmadan, tulumlar test kapsamı analizimi düzgün bir şekilde rapor edemezdi. İyi ki GitHub Actions CI, ana şubeye gönderilmeden önce hatayı işaret etti.

Not: Bunlar, işi iki işe ayırmadan önce çekildi. Ayrıca, kapsama komut dosyamın sonuna --verbose
bayrağını eklediğim için terminalimde kapsam özetini ve hata mesajını görebildim.
Çözüm
Projelerimiz için sürekli entegrasyonu nasıl kuracağımızı ve ayrıca GitHub tarafından sağlanan Eylemleri kullanarak test kapsamını nasıl entegre edebileceğimizi görebiliriz. Bunun projenizin ihtiyaçlarına uyacak şekilde ayarlanabileceği pek çok başka yol var. Bu eğitimde kullanılan örnek depo gerçekten küçük bir proje olmasına rağmen, daha büyük bir projede bile sürekli entegrasyonun ne kadar gerekli olduğunu görebilirsiniz. Artık işlerim başarıyla yürütüldüğüne göre, şubeyi ana şubemle birleştirme konusunda kendime güveniyorum. Yine de, tamamen başarılı olduğunu görmek için her çalıştırmadan sonra adımların sonuçlarını okumanızı tavsiye ederim.