“Çalışmıyor” hangi aşamada?
Sabah çalışması gereken otomasyonu bekliyorsunuz ama sonuç ortada yok. İlk ayrım şu: GitHub Actions sayfasında o saate ait bir çalıştırma var mı? Hiç kayıt yoksa zamanlama, workflow’un etkinliği veya olayın oluşması tarafını araştırın. Kayıt var ama bekliyorsa kuyruk ve runner kapasitesine bakın. Çalışma başlamış ve kırmızı olmuşsa artık cron değil, adımların logları konuşur. Yeşil görünmesine rağmen dosya veya bildirim yoksa koşullar ve uygulamanın kendi iş mantığına dönün. Bu ayrım gereksiz yere cron ifadesini tekrar tekrar değiştirmenizi önler; her aşamanın kanıtı farklıdır.
Bu rehberdeki GitHub kuralları 15 Ekim 2026 tarihindeki resmî belgeye dayanır. Özellikle eski içeriklerdeki “GitHub yalnız UTC destekler” cümlesi artık koşulsuz doğru değildir: UTC varsayılandır, schedule öğesine IANA saat dilimi eklenebilir. Aşağıdaki Python saat dönüşümleri yerelde çalıştırıldı. Örnek workflow bu çalışma kapsamında bir GitHub deposuna gönderilmedi ve GitHub tarafından zamanlanarak çalıştırılmadı. Dolayısıyla yerel çıktılar hizmetin kuyruğu, etkinlik politikası veya gerçek tetikleyicisi için bir başarı iddiası değildir. Kendi deponuzda tamamlayacağınız kontrol akışı ayrıca gösteriliyor.
UTC varsayılanı ve güncel timezone alanı
Saat dilimi verilmezse 17 6 * * 1-5 ifadesi hafta içi 06:17 UTC anını hedefler. Europe/Istanbul için bu yazıdaki tarihlerde karşılığı 09:17’dir. İsteğiniz iş günlerinde İstanbul duvar saatine göre 09:17 ise schedule öğesinin altına timezone: Europe/Istanbul yazarak cron saatini 9 bırakabilirsiniz. İki yaklaşımı aynı anda uygulamayın: saati önce UTC’ye çevirip sonra İstanbul saat dilimi eklemek üç saatlik ikinci bir kayma üretir. timezone anahtarı cron ile aynı liste öğesinde durur; job ortamına TZ eklemek ise zamanlayıcının kararını değiştirmez, yalnız çalışan süreçlerin saat gösterimini etkiler.
01name: Schedule diagnostic02on:03 workflow_dispatch:04 schedule:05 - cron: '17 9 * * 1-5'06 timezone: 'Europe/Istanbul'07permissions:08 contents: read09jobs:10 inspect:11 runs-on: ubuntu-latest12 timeout-minutes: 513 steps:14 - name: Record trigger and runner clock15 env:16 EVENT_NAME: ${{ github.event_name }}17 REF_NAME: ${{ github.ref }}18 SCHEDULE: ${{ github.event.schedule }}19 run: |20 printf 'event=%s\nref=%s\nschedule=%s\n' "$EVENT_NAME" "$REF_NAME" "$SCHEDULE"21 date -u '+UTC=%Y-%m-%dT%H:%M:%SZ'22 TZ=Europe/Istanbul date '+Istanbul=%Y-%m-%dT%H:%M:%S%z'23 Örnekte dakikayı 17 seçmek her saat başındaki yoğunluğa yığılmayı azaltmaya yönelik bir tercihtir; dakik çalıştırma garantisi değildir. workflow_dispatch elle tanı çalışması başlatabilmek için eklenmiştir. Örneğin yalnız saat ve olay bilgisi basması, tetikleyiciyi uygulamanızın ağ çağrıları veya veri tabanı bağımlılıklarından ayrı gözlemlemeyi kolaylaştırır. Gerçek işinizi eklerken gerekli izinleri ve sırları kendi ihtiyacınıza göre tanımlayın. Başarılı elle çalıştırma adımların başlayabildiğini gösterir; schedule olayının gerçekten geldiğini kanıtlamak için olay türü schedule olan ayrı bir kayıt görmeniz gerekir.
Beş alanı doğru okuyun
GitHub Actions için cron beş alandır: dakika, saat, ayın günü, ay ve haftanın günü. İşletim sistemi cron satırındaki kullanıcı veya komut buraya eklenmez. Saniye alanı kullanan başka bir ürünün altı alanlı ifadesini de doğrudan taşımayın. Cron değerini YAML içinde tırnaklayın; özellikle yıldızla başlayan değerlerin YAML tarafından başka şekilde yorumlanmasını önleyin. Her beş dakikada bir için */5 * * * * biçimini kullanın; */5 9 * * * yalnız dokuzuncu saat içinde beşer dakika aralığı demektir. Gerekli olmayan gün kısıtlarını yıldız bırakarak ifadenin niyetini sade tutun.
| İfade | Niyet |
|---|---|
| 17 9 * * 1-5 | Hafta içi 09:17 |
| */15 * * * * | Her saatin 00, 15, 30, 45. dakikası |
| 17 9 1 * * | Her ayın ilk günü 09:17 |
Zamanlama adayıdır; fiilî başlama zamanı kuyruktan etkilenir.
Workflow doğru dalda mı?
Önce depo ayarlarından varsayılan dalın adını bulun; bunun her projede main olduğunu varsaymayın. Zamanlanan workflow dosyası o dalın .github/workflows dizininde bulunmalıdır. GitHub schedule çalıştırmalarını varsayılan dalın son commit’i üzerinden oluşturur. Yeni dosyayı yalnız bir özellik dalına göndermek veya açık pull request içinde tutmak zamanlamayı etkinleştirmez. Dosyanın adı ve uzantısını, YAML girintisini ve Actions sekmesinde workflow’un tanınıp tanınmadığını kontrol edin. Örneğin job içindeki checkout ile başka dal seçmek kaynak dosyalarını değiştirebilir ama schedule olayının hangi dal üzerinden oluştuğu kuralını değiştirmez.
Elle çalıştırma düğmesini görmüyorsanız workflow_dispatch tanımını ve dosyanın varsayılan daldaki sürümünü de kontrol edin. Zamanlama teşhisini kolaylaştırmak için ilk denemeyi varsayılan dalda, yalnız tanı çıktısı veren iş ile yapın. Gerçek uygulama koduna geçmeden tetikleyici ve job görünürlüğünü doğrulayın. Actions sayfasında ilgili workflow’un devre dışı olup olmadığına ve depo veya kuruluş düzeyindeki Actions politikasına bakın. Çalıştırma gerçekten oluşmuşsa artık dalı sürekli değiştirmek yerine oluşan kaydın olay türünü, commit bilgisini ve adım durumlarını okuyun. Bu bilgiler varsayımı somut bir gözleme dönüştürür.
Hareketsizlik, kuyruk ve asgari aralık
GitHub’ın güncel schedule belgesinde public depolar için 60 gün depo etkinliği olmadığında zamanlanan workflow’ların otomatik devre dışı kalabileceği belirtilir. Böyle bir durumda Actions arayüzünden etkinliği kontrol edip yeniden etkinleştirme yolunu uygulayın. Aynı belge en kısa zamanlama aralığını beş dakika olarak verir. Daha kısa bir cron yazıp bunu hassas bir zamanlayıcı gibi kullanmaya çalışmayın. Yoğun dönemlerde schedule olayı gecikebilir; belge yeterince yüksek yükte bazı kuyruk işlerinin düşebileceğini de söyler. Bu nedenle saniyesi saniyesine bildirim, kritik ödeme veya kesin teslim saati isteyen bir işte yalnız cron tetikleyicisine güvenmeyin.
Günlük rapor gibi yeniden üretilebilir işlerde son başarılı iş tarihini kalıcı olarak tutup eksik günleri sonraki çalışmada tamamlamak pratik bir tasarımdır. Aynı dönemin iki kez işlenmesi dış sistemde iki kayıt açmamalıdır; dönem anahtarı veya benzeri bir tekrar önleme kuralı kullanın. Kuyruk gecikmesini cron ifadesini değiştirerek tamamen ortadan kaldıramazsınız. Başlama saati, bitiş saati ve işlenen veri aralığını loglamak ise sorunun zamanlama mı yoksa işleme süresi mi olduğunu ayırmanıza yardım eder. Bunlar GitHub’ın size sağladığı bir garanti değil, uygulamanızın gecikmeye dayanmasını sağlayan tasarım kararlarıdır.
Saat dönüşümünü yerelde sınayın
İstanbul ve New York örneklerini iki tarihte karşılaştırmak sabit UTC farkı ile bölgesel saat dilimini neden karıştırmamak gerektiğini gösterir. Aşağıdaki programın 09:17 değerleri geçiş saatlerinin dışında seçilmiştir; genel bir cron motoru veya yaz saati geçiş simülatörü değildir. Python zoneinfo, kurulu IANA saat dilimi verisini kullanır. İstanbul örneklerinde fark aynı kalırken New York’ta yaz ve kış farkı değişir. Gerçek iş gereksinimi “yerel saatle dokuz” ise yalnız bir günün UTC karşılığını hesaplayıp bütün yıl için sabitlemek başka bölgelerde niyeti bozabilir.
01from datetime import datetime, timezone02from zoneinfo import ZoneInfo03 04istanbul = ZoneInfo("Europe/Istanbul")05for day in ("2026-10-15", "2026-12-15"):06 local = datetime.fromisoformat(day + "T09:17:00").replace(tzinfo=istanbul)07 print(local.isoformat(), "=>", local.astimezone(timezone.utc).isoformat())08 09new_york = ZoneInfo("America/New_York")10for day in ("2026-07-15", "2026-12-15"):11 local = datetime.fromisoformat(day + "T09:17:00").replace(tzinfo=new_york)12 print(local.isoformat(), "=>", local.astimezone(timezone.utc).isoformat())012026-10-15T09:17:00+03:00 => 2026-10-15T06:17:00+00:00022026-12-15T09:17:00+03:00 => 2026-12-15T06:17:00+00:00032026-07-15T09:17:00-04:00 => 2026-07-15T13:17:00+00:00042026-12-15T09:17:00-05:00 => 2026-12-15T14:17:00+00:00Yaz saati geçişlerindeki var olmayan veya yinelenen duvar saatlerini platformunuzun belgelerine göre ayrıca ele alın. Python ile bir tarihe tzinfo bağlamak GitHub’ın zamanlama politikasını simüle etmez. Loglarda saat dilimi olmayan 09:17 yazısı yerine UTC işaretli ISO 8601 zamanını saklamak karşılaştırmayı kolaylaştırır. Bir logun zaman damgasını Unix zaman damgası dönüştürücü ile okuyup İstanbul gösterimiyle yan yana inceleyebilirsiniz. Zaman damgasının saniye mi milisaniye mi olduğunu da doğrulayın; birim hatası, saat dilimi hatasına benzer derecede yanlış sonuç üretir.
Kendi deponuzda nasıl doğrularsınız?
Örnek workflow’u kendi deponuzun varsayılan dalına alın ve önce elle çalıştırın. Olay adının workflow_dispatch olduğunu görüp saat çıktısını inceleyin. Daha sonra seçtiğiniz schedule zamanından sonraki kayıtları açın; olay adı schedule olmalı ve cron değeri beklediğiniz ifadeyle eşleşmelidir. Kaydın oluşmasıyla runner’ın başlaması arasındaki süreyi de değerlendirin. Geçerli bir yerel önizleme yalnız aday saatleri açıklar; bu kayıtların yerini tutmaz. Hiç kayıt oluşmuyorsa dal, devre dışı olma ve politika kontrollerine dönün; kayıt başarısızsa ilk hata veren adımı okuyun.
İfade kurarken cron oluşturucu ile beş alanı ve seçtiğiniz saat dilimini birlikte kontrol edin. Önizlemeyi iş takviminizden birkaç tarih ile karşılaştırın; ay sonu ve yıl değişimi gibi örnekleri atlamayın. Workflow dosyasına kısa bir yorumla saat gereksinimini yazın: “hafta içi İstanbul 09:17”. Bu ifade gelecekte saati değiştiren kişiye cron sayılarından daha iyi bağlam verir. Son olarak çalışan uygulamanın kendi takvimini ayrı tutun: rapor günü tetiklenme anından mı, İstanbul tarihinden mi yoksa son tamamlanan dönemden mi hesaplanıyor? Tetikleyici doğruyken yanlış günün verisini işlemek de dışarıdan bakınca “cron çalışmadı” gibi görünebilir.
Resmî kaynaklar
GitHub ve Python belgeleri 15 Ekim 2026’da kontrol edildi.
- GitHub: Events that trigger workflows — schedule
- GitHub: Manually running a workflow
- GitHub: Disabling and enabling a workflow
- GitHub: Workflow syntax
- Python: zoneinfo — IANA time zone support
Yerel Python saat dönüşümleri çalıştırıldı. Workflow GitHub’a gönderilmedi veya zamanlanarak çalıştırılmadı; hizmetin güncel davranışı için resmî belgeyi kontrol edin.
İfadeyi saat dilimiyle birlikte inceleyin, ardından gerçek olay kaydını doğrulayın.
Cron oluşturucuyu aç ↗