Sürüm kontrol kancalarında birim testlerini yapmak iyi bir uygulama mıdır?


43

Teknik açıdan, bazı özel işlemlerin uzak varsayılan şubeyle birleştirilmesine izin vermeden önce birim testlerini gerçekleştirecek ön / son basma kancaları eklemek mümkündür.

Benim sorum şu - birim testlerini inşa boru hattında tutmak (bu nedenle, repo için bozuk taahhütler getirmek) daha mı iyidir, yoksa "kötü" taahhütlerin gerçekleşmesine izin vermemek daha iyidir.

Bu iki seçenekle sınırlı olmadığımı biliyorum. Mesela, bir bütün olarak repo taahhüdünü zorlamadan önce tüm taahhütlerin dallanmasına ve test etmesine izin verebilirim. Ancak, tam olarak bu iki çözüm arasında seçim yapmak zorunda kalırsanız, hangisini seçmelisiniz ve hangi sebeplerden dolayı?


Yanıtlar:


35

Hayır, iki nedenden dolayı değil:

hız

Taahhütler hızlı olmalıdır. Örneğin, 500 msn süren bir taahhüt çok yavaştır ve geliştiricilerin daha dikkatli davranmalarını teşvik edecektir. Bir Hello Dünyasından daha büyük herhangi bir projede, onlarca veya yüzlerce test yapacağınız göz önüne alındığında, ön işleme sırasında bunları çalıştırmak çok zaman alacaktır.

Tabii ki, dağıtık bir mimaride dakikalarca veya tek bir makinede haftalarca veya aylarca süren binlerce testle daha büyük projeler için işler kötüye gidiyor.

En kötü yanı, daha hızlı hale getirmek için yapabileceğiniz pek bir şey olmamasıdır. Yüzlerce birim testi olan küçük Python projeleri ortalama bir sunucuda çalıştırmak için en az bir saniye alıyor, ancak çoğu zaman çok daha uzun sürüyor. Bir C # uygulaması için, derleme süresi nedeniyle ortalama dört-beş saniye olacaktır.

Bu noktadan sonra, zamanı azaltacak daha iyi bir sunucu için fazladan 10.000 $ ödeyebilirsiniz, ancak çok fazla değil veya birden fazla sunucu üzerinde testler uygulayabilirsiniz, bu da işleri yavaşlatır.

Her ikisi de, binlerce sınava (ve ayrıca işlevsel, sistem ve entegrasyon sınamalarına) sahip olduğunuzda iyi ödeme yapar ve haftalar yerine dakikalar içinde çalıştırmanıza olanak tanır, ancak bu küçük ölçekli projeler için size yardımcı olmaz.

Bunun yerine, yapabilecekleriniz:

  • Geliştiricileri, bir taahhütte bulunmadan önce yerel olarak değiştirilen kodlarla ilgili testleri güçlü bir şekilde yürütmeye teşvik edin. Muhtemelen binlerce ünite testi yapamazlar, ancak ondan beşini çalıştırabilirler.

    İlgili testleri bulup çalıştırmanın gerçekten kolay (ve hızlı) olduğundan emin olun. Örneğin Visual Studio, son testten bu yana yapılan değişikliklerden hangi testlerin etkilenebileceğini tespit edebiliyor. Diğer IDE'ler / platformlar / diller / çerçeveler benzer işlevlere sahip olabilir.

  • Taahhüdü mümkün olduğunca hızlı tutun. Stil kurallarını uygulamak tamamdır, çünkü çoğu zaman, bunu yapacak tek yer burasıdır ve bu tür kontroller genellikle inanılmaz derecede hızlıdır. Statik analiz yapmak hızlı kaldığı anda tamamdır, bu nadiren durumdur. Çalışan ünite testleri iyi değil.

  • Sürekli Entegrasyon sunucunuzda birim testlerini çalıştırın.

  • Geliştiricilerin yapıyı bozduklarında otomatik olarak bilgilendirildiğinden emin olun (veya birim testleri başarısız olduğunda, bir derleyiciyi kodunuza girebileceğiniz olası hataların bazılarını kontrol eden bir araç olarak görürseniz pratik olarak aynı şeydir).

    Örneğin, son yapıları kontrol etmek için bir web sayfasına gitmek bir çözüm değildir. Otomatik olarak bilgilendirilmeleri gerekir . Bir açılır pencerenin gösterilmesi veya SMS gönderilmesi, nasıl bilgilendirilebileceklerinin iki örneğidir.

  • Geliştiricilerin yapıyı kırmanın (veya başarısızlık regresyon testlerinin) tamam olmadığını ve en kısa zamanda önceliklerinin bunu düzeltmek olduğunu anladığından emin olun. Patronlarının yarın için göndermelerini istedikleri yüksek öncelikli bir özellik üzerinde çalışıp çalışmadıkları önemli değil: yapıyı bozdular, düzeltmeleri gerekiyor.

Güvenlik

Depoyu barındıran sunucu, özellikle güvenlik nedeniyle birim testleri gibi özel kodlar çalıştırmamalıdır. Bu nedenler zaten GitLab'ın aynı sunucusunda CI koşucusunda açıklandı mı?

Öte yandan, fikriniz, derleme sunucusundaki ön işleme kancasından bir işlem başlatmaksa, o zaman işleri daha da yavaşlatır.


4
Katılıyorum, bu bir yapı sunucusu içindir. Kaynak kontrolünüz, uygulamanızın çalışmasını sağlamak yerine kaynak kodunu yönetmek içindir.
Matthew,

4
Aşırı durumlarda, misilleme yapıyı keserken gerekli bir bildirim aracı olabilir.

37
Yarım saniye çok mu yavaş? Bu, kovalanana, neyin işlendiğine bir son bakış atmaya ve ardından uygun bir yorum yazmayı düşünmeye ve yazmaya nazaran bir düşüş.
Doval

5
@Doval: Aradaki fark şu ki, son bir bakış attığınızda ya da yorumu düşündüğünüzde proaktif olursunuz ve dolayısıyla beklemiyorsunuzdur. IDE'nizdeki son karakteri yazmadan önce harcadığınız zaman değil ve işiniz bittikten sonra tekrar yazmaya başlayabileceğiniz zaman değil, ne kadar beklersiniz. Bu nedenle derleyiciler hızlı olmalı; kod okumak ve yazmak için çok daha fazla zaman harcamanızın önemi yoktur, çünkü bunu yaparken beklemiyorsunuzdur, oysa kod derlenirken farklı bir etkinliğe geçmeye istekli olursunuz.
Arseni Mourzenko

10
@ Tommalar: Bu dikkat dağıtıcı değil, rahatsızlık ile ilgili. Aynı şekilde, 100 ms. İnsanların bir web sitesini nasıl kullandıkları üzerinde "ölçülebilir bir etkisi vardır" . Burada aynı desen: 100 ms. bir YouTube videosunu izlemek veya bilgisayarınızı başlatmak için harcadığınız zamanla karşılaştırıldığında hiçbir şey değildir : bilinçli olarak , 600 msn arasındaki farkı farketmezsiniz. ve 700 ms. gecikme. Ama bilinçsizce, davranışlarınız üzerinde bir etkisi var. Aynı şekilde, biraz daha yavaş taahhütler sizi erken ve sık taahhüt etmenizden caydırır.
Arseni Mourzenko 24:14

41

Cevap arkadaşlarım ile aynı fikirde olmayan biri olalım.

Bu, TFS dünyasında Geçitli Girişler olarak bilinir ve başka bir yerde beklerim. Girişli girişli bir şubeye giriş yapmaya çalıştığınızda, raf seti sunucuya gönderilir, bu da değişikliklerin artmasını ve belirtilen (okuma: tümü) birim testlerinin başarılı olmasını sağlar. Olmazlarsa, yapıyı bozan kötü bir maymun olduğunuzu size bildirir. Bunu yaparlarsa, değişiklikler kaynak kontrolüne girer (yay!).

Tecrübelerime göre, kapılı check-in'ler başarılı ünite testleri için ve en önemlisi yazılım kalitesi için en önemli süreçlerden biridir.

Neden?

  • Çünkü kapılı check-in'ler insanları kırık testler yapmaya zorlar. En kısa sürede kırık testler şey insanlar olduklarında olabilir yapmak yerine gerekir yapmak, onlar de-öncelik haline tembel mühendis ve / veya saldırgan iş adamları tarafından.
    • Bir test ne kadar uzun süre bozulursa, o kadar zorlaşır (ve daha pahalı).
  • En kısa sürede insanlar olarak Çünkü gerektiğini testler yerine gerekir testler, testler tembel / unutkan mühendis ve / veya saldırgan iş adamları tarafından ihlal edilmektedir.
  • Çünkü ünite testleri sizin taahhüt sürenizi etkilediğinde, insanlar gerçekten ünite testleri yapmak için özen göstermeye başlarlar . Hız önemlidir. Yeniden üretilebilirlik önemlidir. Güvenilirlik önemlidir. İzolasyon önemlidir.

Ve elbette, başlangıçta ortaya attığınız fayda var - check-in işlemlerini yaptığınız ve sağlam bir test grubunuz olduğunda, her bir değişiklik seti "kararlıdır". "En son ne zaman iyiydi?" - tüm yapılar karşı geliştirilebilecek kadar iyidir.

Evet, testleri oluşturmak ve çalıştırmak zaman alıyor. Tecrübelerime göre 5-10 dakika boyunca iyi bir C # uygulaması ve ~ 5k birim testleri. Ve bunu umursamıyorum. Evet, insanlar sık ​​sık check-in yaptırmalı. Ancak, görevlerini sık sık güncellemeli, e-postalarını kontrol etmeli ya da bir yazılım mühendisinin bu süreyi işgal etmesini sağlayan kahve ya da düzinelerce "kod üzerinde çalışmıyor" gibi şeyler almalıdırlar. Hatalı kodu kontrol etmek 5-10 dakikadan daha maliyetlidir.


3
+1 Eklemek istiyorum ki, birçok açık kaynaklı projenin katkı ve taahhüt arasında açık bir ayırım olduğunu var. Bunun nedenleri, kapı girişlerinin varlığına çok benzer.
JensG

Girişli check-in işlemlerinde önemli bir problem, zorlu kodların ortak problem çözülmesini engellemesidir. Bu, dağıtılmış ekipler için daha da önemlidir.
CuriousRabbit

2
@CuriousRabbit - nasıl anladın? İnsanlar nadiren taahhüt onlar bile işbirliği çalışması işbirliği. Aksi halde raflar veya tarihsiz görev dalları, ekibin geri kalanını engellemeyecek şekilde çalışır.
Telastyn

@ Telastyn - Raflar benim için yeni bir terimdir. Bunun çok sayıda proje için seçenek olmayan bir MS VS seçeneği olduğunu biliyorum. Mobil uygulama geliştirme alanında, VS bir oyuncu değil.
CuriousRabbit

3
@CuriousRabbit - gerçekten mi? 17 saatten fazla dağıtılan bir ekip, rahatsız edici parti uyurken, kırılmış bir inşa olasılığından daha 10 dakika beklemekle ilgileniyor mu? Bu görünüyor ... Optimal daha az.
Telastyn

40

Komisyonların hızlı çalışması gerekir. Bazı kodlar işlediğimde sunucuya gönderilmesini istiyorum. Bir test bataryası sürerken birkaç dakika beklemek istemiyorum. Sunucuya zorladığımdan sorumluyum ve bana kancalarla bakıcılık yapan kimseye ihtiyacım yok.

Bu, sunucuya ulaştığında, analiz edilmeli, ünite testinden geçirilmeli ve derhal (veya kısa bir süre içinde) yapılmalıdır. Bu beni ünite testlerinin kırıldığı veya derlemediği konusunda uyarır ya da mevcut statik analiz araçlarının gösterdiği bir karışıklık yarattı. Bu ne kadar hızlı yapılırsa (derleme ve analiz), geribildirimlerim o kadar hızlı ve bunu daha hızlı düzeltebilirim (düşünceler beynimden tamamen değişmedi).

Bu yüzden hayır, müşteriye testler vb. Gerekirse, bunları sunucuya bir posta yükleme görevi (çünkü bir CI sunucunuz olmadığı için) veya CI derleme sunucusuna koyun ve beni kodla ilgili sorunlara karşı uyarın. Ancak, ilk önce taahhüdün gerçekleşmesini engellemeyin.

Ayrıca Test Odaklı Gelişme'nin bazı yorumlarıyla birinin önce kırılan bir birim testine girmesi gerektiğini de belirtmeliyim . Bu, hatanın mevcut olduğunu gösterir ve belgeler. Sonra bir sonraki kontrol birim testini düzelten kod olacaktır . Birim testlerinin geçmesine kadar herhangi bir kontrol işleminin engellenmesi, sorunu belgelemeyen bir birim testinde kontrol etmenin etkin değerini azaltacaktır.

İlgili: Bilinen kusurlar için birim testleri yapmalı mıyım? ve başarısız ünite testlerinde kontrolün değeri nedir?


2
Commits should run fast.bunun faydaları nelerdir? Merak ediyorum çünkü şu anda kapılı checkin kullanıyoruz. Genelde check-in'lerim bir saatlik ya da daha fazla işin toplamıdır, bu yüzden 5 dakikalık bir bekleme büyük bir mesele değildir. Aslında normalde, doğrulama yapısının aptalca hataları yakalamak için çok yararlı olduğunu (acele etmenin bir sonucu olarak) olduğum zamanları buldum
Justin

1
@Justin Nerede olursanız olun, beş dakikalık bir bekleme, beş dakikalık bir beklemedir. Ne zaman bir iş yaparsan inek kılıçlarını parçalamak zorunda kalmamalısın . Ve benim bir saatlik çalışmamı, birbirlerinin kavramsal birimleri olan birden fazla komisyona ayırmam - nadiren değil - "dinlenme servis kodunu taahhüt et" ve ardından "hizmet verilen müşteri sayfası için kodu taahhüt et" ve iki ayrı komisyon olarak (Css tweak başka bir taahhüt olarak söz değil). Bunların her birinin çalışması 5 dakika sürerse, zamanımın 1 / 6'sı testleri beklemekle geçiyor. Bu, hataları takip

Birim testleri çalıştırmak için 5 dakika bekleyin? Üzerinde çalıştığınız projelerin daha küçük parçalara bölünmesi gerektiğini düşünüyorum.
kullanıcı441521,

@Justin catching silly mistakes (as a result of rushing)tam olarak. acele genel olarak yazılım mühendisliğinde kötü bir uygulamadır. Robert C. Martin ameliyat yapmak gibi bir kod yazmanızı önerir youtube.com/watch?v=p0O1VVqRSK0
Jerry Joseph

10

Prensip olarak, insanların yapıyı bozan ana hatta değişiklikler yapmalarını önlemenin mantıklı olduğunu düşünüyorum. Yani, deponuzun ana şubesinde değişiklik yapma süreci tüm testlerin hala geçmesini sağlamalıdır. Yapıyı kırmak, projedeki tüm mühendislerin başka bir şey yapması için zaman kaybı açısından çok masraflı.

Bununla birlikte, özel taahhüt kancalarının çözümü iyi bir plan değildir.

  1. Geliştiricinin test sırasında çalışmasını beklemesi gerekir. Geliştirici tüm testlerin geçmesi için iş istasyonunda beklemek zorunda kalırsa, değerli mühendis zamanınızı boşa harcarsınız. Mühendislerin bir sonraki göreve geçebilmeleri gerekiyor, testler başarısızlıkla sonuçlandığından geri dönmek zorunda olsa bile.
  2. Geliştiriciler bir dalda bozuk kod vermek isteyebilirler. Daha büyük bir görevde, kodun geliştiriciler sürümü geçme durumunda değil çok zaman harcayabilir. Açıkçası, bu kodu ana hatta dahil etmek çok kötü olurdu. Ancak geliştiricinin ilerlemesini izlemek için sürüm kontrolünü kullanabilmesi oldukça önemlidir.
  3. Süreci atlamak ve testleri atlamak için zaman zaman iyi nedenler olabilir.

2
# 1, geliştiricilerin kişisel bir şubeye veya yerel bir depoya check-in yapmasına izin vermekle suçlanmaktadır. Yalnızca bir geliştirici kodunu başka bir yerde istediğinde, diğer geliştiricilerin birim testlerinin çalışması gerektiğini görebileceği bir yerde olmasını ister. # 1 ile olduğu gibi, # 2 yalnızca ana hatlara giden kancalarla engellenir. # 3, A) 'nın herhangi bir zorluğa rağmen (ve bir güçlük olması gerektiği gibi) ve B) Bireysel başarısız ünite testleri devre dışı bırakılabilir.
Brian,

@Brian, tamamen anlaşmadayım, bu işi yapabilirsiniz. Ancak, taahhüt çengel sunucu tarafı bloke ederek yapmaya çalışmak işe yaramaz.
Winston Ewert

güzel nokta. Breaking the build is simply too costly in terms of lost time for all engineers on the projectHer mühendisin kırılmış her yapının zamanını kaybetmesini engellemek için bir tür bildirim bildirimi aracı kullanmanızı öneririm
Jerry Joseph

3

Hayır, diğer cevapların işaret ettiği gibi olmamalısınız.

Başarısızlık testi yapılmayan garantili bir kod tabanına sahip olmak istiyorsanız, bunun yerine özellik dallarında gelişebilir ve istekleri master'a çekebilirsiniz. Ardından, bu çekme isteklerini kabul etmek için ön koşulları tanımlayabilirsiniz. Bunun yararı, gerçekten hızlı bir şekilde bastırabilmeniz ve testlerin arka planda çalışmasıdır.


2

Başarılı bir şekilde kurulmasını beklemek ve her ana dalda yapılan testlerin test edilmesi gerçekten de çok zor, sanırım herkes bu konuda hemfikir.

Ancak tutarlı bir ana dal elde etmenin başka yolları da var. Aşağıda, TFS'deki kapılı check-in damarlarına biraz benzeyen, ancak çoğunlukla git terimlerini kullanmama rağmen şubeli herhangi bir sürüm kontrol sistemine genelleştirilebilecek bir öneri:

  • Sadece dev şubelerinizle ana şubeniz arasında birleşebilecek bir sahneleme şubesi olsun.

  • Bir yapıyı başlatan ya da sıraya alan ve aşama dalında yapılan işlemleri denetleyen bir kanca ayarlayın, ancak bu, işletmeciyi bekletmez

  • Başarılı kurulum ve testlerde güncel ise , ana şubenin otomatik olarak ilerlemesini sağlayın

    Not: otomatik olarak ana dalı birleştirmeyin , çünkü test edilmiş birleştirme, ana dalın bakış açısından bir ileri birleşme değilse, ana dalda birleşme söz konusu olduğunda birleştirildiğinde başarısız olabilir.

Sonuç olarak:

  • Yasaklı insan, ana şubeye, eğer mümkünse otomatik olarak değil, aynı zamanda bir kaçamak varsa veya resmi olarak uygulamak için teknik olarak uygun değilse, resmi sürecin bir parçası olarak taahhüt eder.

    En azından kimsenin istemeden veya kötüye kullanmadan, temel kural olduğu zaman, bunu yapmayacağından emin olabilirsiniz. Bunu asla yapmaya çalışmamalısın.

  • Şunlardan birini seçmelisin:

    • Aksi halde başarılı olacak birleştirmeleri gerçekleştirecek olan tek bir hazırlama şubesi, daha önce oluşturulmamış ve test edilmemiş bir birleştirme başarısız olursa, aslında başarısız olur.

      En azından, hangi birleştirme işleminin başarısız olduğunu ve birisinin onu düzeltmesini sağladığını anlayacaksınız, ancak aradaki birimler daha fazla derleme ve testlerin sonuçları için önemsiz şekilde izlenemez (sürüm kontrol sistemi tarafından).

      Dosya ek açıklamalarına (veya suçlamaya) bakabilirsiniz, ancak bazen bir dosyadaki değişiklik (örn. Yapılandırma) beklenmeyen yerlerde hatalara neden olabilir. Ancak, bu oldukça nadir bir olaydır.

    • Çakışmayan başarılı birleştirme işlemlerinin ana şubeye ulaşmasına olanak tanıyan birden fazla hazırlama dalı

      Başka bir basamaklandırma şubesinin çelişkili olmayan başarısızlık birlikleri olması durumunda bile . İzlenebilirlik biraz daha iyidir, en azından bir birleşmenin başka bir birleşmeden etkilenen bir değişiklik beklememesi durumunda. Fakat yine de, bu her gün veya her hafta için endişelenmeyecek kadar nadirdir.

      Çatışmayan çoğu zaman birleşmeleri sağlamak için, hazırlama ekiplerini hassas bir şekilde bölmek önemlidir, örneğin ekip başına, katman başına veya bileşen / proje / sistem / çözüm başına (ne şekilde adlandırırsanız).

      Bu arada ana şube başka bir birleştirme işlemine yönlendirildiyse, tekrar birleştirmek zorundasınız. Umarım, bu çelişkili olmayan birleşme veya çok az çatışma ile bir sorun değildir.

Geçitli check-in'lere kıyasla, buradaki avantaj, çalışan bir ana şubenin garantisidir, çünkü ana şubenin yalnızca ileriye gitmesine izin verilir, değişikliklerinizi aralarında yapılanlarla otomatik olarak birleştirmezsiniz. Yani üçüncü nokta, temel farktır.


Ancak, bir çalışma koluna sahip olmanın amacı (genellikle) istikrarlı bir salıvermenizin sağlanması değil, aynı kodda birlikte çalışan geliştiricilerin yarattığı sarsıntıyı azaltmaktır.
Telastyn

Büyük, dünya çapında dağıtılan ekiplerle büyük bir repo varsa. Örneğin, Microsoft, Windows ile benzer, daha katmanlı bir yaklaşım kullanmaktadır.
acelent

2

Kod girme giriş kapısı olarak "başarılı birim testlerini" tercih ediyorum. Ancak, bu işi yapmak için birkaç şeye ihtiyacınız olacak.

Eserlerin önünü açan bir yapı çerçevesine ihtiyacınız olacak.

Herhangi bir artefaktla (başarılı) test çalışmalarından test durumunu önbelleğe alan bir test çerçevesine ihtiyacınız olacak.

Bu şekilde, geçen birim testleriyle yapılan check-in'ler hızlı olacaktır (kaynaktan, geliştirici giriş öncesi testleri kontrol ettiğinde yapılan artefakta çapraz kontrol), başarısız ünite testine sahip olanlar engellenecek ve Derleme ve test döngüsü uzun olduğu için, işlemden önce yapıları kontrol etmeyi unutmadan, bir dahaki sefere bunu hatırlamaya teşvik edilecektir.


1

Projeye ve “taahhütte” yapılan otomatik testlerin kapsamına bağlı olduğunu söyleyebilirim.

Giriş tetiklemesinde çalıştırmak istediğiniz testler gerçekten hızlıysa veya geliştirici iş akışı zaten böyle bir check-in işleminden sonra bazı idari işleri zorlarsa, bunun önemsiz olması gerektiğini düşünüyorum ve devleri sadece kontrol etmeye zorlar. kesinlikle en temel testleri yapan şeylerde. (Böyle bir tetikleyicide sadece en temel testleri yapacağınızı farz ediyorum.)

Ve hız / iş akışının izin verdiğine inanıyorum, testlerde başarısız olan diğer geliştiricilere yapılan değişiklikleri zorlamamak iyi bir şeydir - ve sadece onları çalıştırırsanız başarısız olduklarını bilirsiniz.

Soruda "uzak şubeye taahhütte" yazıyorsunuz, ki bu bana (a) bir devin birkaç dakikada bir yaptığı bir şey değil, bu yüzden küçük bir bekleme çok iyi kabul edilebilir olabilir, ve (b) Böyle bir taahhüt, kod değişikliklerinin diğer aygıtları etkileyebileceği için, ek kontroller sırayla yapılabilir.

Böyle bir işlem için "dev'lerinizi beklerken başparmaklarınızı kırma" konulu diğer cevaplarla aynı fikirdeyim.


1

Gövde üzerinde parçalanan komisyonlara izin verilmemelidir , çünkü gövde üretime girebilecek olan şeydir. Bu yüzden bagaja geçmeden önce geçmeleri gereken bir ağ geçidi olduğundan emin olmalısınız . Ancak, kesilen taahhütler, bagajda olmadığı sürece bir depoda tamamen iyi olabilir.

Öte yandan, geliştiricilerin depodaki değişiklikleri zorlamadan önce sorunları beklemesini / düzeltmesini gerektirmesi bazı dezavantajlara sahiptir.

Bazı örnekler:

  • TDD'de, özelliği uygulamaya başlamadan önce yeni özellikler için başarısız testler yapmak ve zorlamak yaygındır.
  • Aynı şey başarısız bir testi taahhüt ederek ve iterek hataları bildirmek için de geçerlidir.
  • Eksik kod basmak, 2 veya daha fazla kişinin bir özellik üzerinde paralel olarak kolayca çalışmasını sağlar
  • CI altyapınızın zaman doğrulamasını alabilir, ancak geliştiricinin beklemesi gerekmez
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.