Modül Güncellemesi Yayınlama

1.6k görüntülenme Markdown

Yeni bir sürümü zaten kurmuş sistemlere ulaştırın: tek manifest, tek sürüm, tek operatör kararı.

Genel Bakış

Sistem günde bir kez ne yayınlandığını sorar; yayıncı sürüm, changelog ve ürün kartıyla yanıt verir. Yeni bir yanıt bildirim açar, güncelleme tıklanınca çalışır.

Bir dizin manifest.json taşıyarak güncellenebilir olur; yoksa o kopyaya dokunulmaz.

gönderdiğiniz sözleşmenin tamamı
{"type":"marketplace","id":42,"version":"1.2.0","last_updated":"2026-08-03"}

Ön Koşullar

Yayınlanmış bir kayıt Tespit kimliğe göre sorar: marketplace sayısal id, store anahtar adı.
Yalnız yukarı giden bir sürüm PHP sürüm karşılaştırması: 2.10.0, 2.4.0'tan yenidir. Yayınlanan numara yeniden kullanılamaz.
Müşterinin sunucusunda ZipArchive Olmadan çıkarma adımı zip_unavailable ile durur.
Yazılabilir bir temp dizini Her iş temp/module-update altında yaşar: arşiv, içerik, geri alma kopyası.
İki kez çalışabilen migration'lar Güncelleme yolunda size ait hiçbir betik çalıştırılmaz.

Yapı

Tespit, karar ve kurulum üç ayrı şeydir.

AşamaKim çalıştırırNe olur
Tespitgünlük zamanlanmış görevHer manifest toplanır ve kaynak başına tek çağrıyla sorulur
BildirimpanelSürüm, changelog ve kartın anlık kopyasını taşıyan zil bildirimi; Şimdi Güncelle ve Daha Sonra
SihirbazoperatörDört tekrarlanabilir istek: indir, çıkar, uygula, bitir; token ile adreslenir

Otomatik kurulum adımı yoktur. Yazdığınız changelog, keşfedildiği gün dondurulur.

Changelog'u düzenlemek bekleyen bildirime ulaşmaz

Tekilleştirme modül artı sürüm üzerindendir ve okunmamış bildirimlere bakar; zilde duran bildirim metnini korur, sonraki koşu yeni satır açar.

Adım Adım

Manifest'i gönderin

manifest.json dosyasını sınıf dosyasının yanına, temada theme.php ile yan yana koyun.

nerede durur
coremio/modules/Addons/AuroraBackup/AuroraBackup.php
coremio/modules/Addons/AuroraBackup/config.php
coremio/modules/Addons/AuroraBackup/manifest.json     <- dizini güncellenebilir yapar

templates/website/Aurora/theme.php
templates/website/Aurora/manifest.json                <- theme.php'nin yanında, yerine değil

Anlaşılamayan bir manifest yok sayılır: bilinmeyen kaynak, eksik sürüm, id'siz marketplace kaydı, adsız store kaydı.

Sürümü yükseltin

Karşılaştırılan tek şey manifest'teki sürümdür. Sistem başarılı uygulamadan sonra kendi kopyasını yazar.

karşılaştırma nasıl yapılır
// İki taraf da önce normalleştirilir: yalnız ilk satır ve yalnız bir sürümü oluşturan
// karakterler; böylece kaçak bir boşluk ya da bir yorum, hiçbir şeye eşit çıkan bir
// sürüm üretemez.
public static function normalize(string $version): string;
public static function is_newer(string $remote, string $local): bool;

// is_newer('2.10.0', '2.4.0')  === true    version_compare, dize sıralaması değil
// is_newer('1.2.0',  '1.2.0')  === false   eşit olan yeni değildir
// is_newer('1.2.0',  '')       === false   okunamayan taraf asla güncelleme tetiklemez

Arşivi biçimlendirin

Arşiv açılır ve içinde dizininiz aranır; doğru görünen ilk düzen kazanır.

  1. Arşivin kökünde, tam olarak modül anahtarı adını taşıyan bir klasör.
  2. Tam ağaç: modül için coremio/modules/{Type}/{Key}, tema için templates/website/{Key}.
  3. Kökte adsız tek bir dizin ya da doğru dosyayı taşıyorsa kökün kendisi.

"Doğru görünmek", modül için {Key}.php, tema için theme.php taşımak demektir; hiçbiri tutmazsa adım package_mismatch ile durur.

Kendi tablolarınızı taşıyın

Güncelleme dosya kopyalar: size ait betik çalışmaz ve enable yolu yeniden çağrılmaz.

hem sıfır kurulumu hem yükseltmeyi atlatan desen
public function enable(): bool
{
    // Sıfırdan kurulum yolu.
    $this->check_database();

    return true;
}

public function adminArea(): array
{
    // Yükseltme yolu: enable() yıllar önce, önceki sürümde çoktan koştu.
    $this->check_database();

    // ...
    return ['page_title' => 'Aurora Backup', 'content' => $this->view('index.php')];
}

/**
 * Eksik olanı oluşturur ve sonradan eklenmiş olanı ekler. Her istekte çağrılması
 * güvenlidir: varlık kontrollerinin kendisi migration'dır.
 */
private function check_database(): void
{
    if (!WDB::hasTable('AuroraBackup_jobs')) {
        WDB::exec('CREATE TABLE `AuroraBackup_jobs` (
            `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
            `user_id` INT UNSIGNED NOT NULL DEFAULT 0,
            `created_at` DATETIME NOT NULL,
            PRIMARY KEY (`id`),
            KEY `owner` (`user_id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci');

        // Her kolon zaten varken oluşturuldu: aşağıdaki hiçbir şeyin koşmasına gerek yok.
        return;
    }

    // 1.2'de eklendi: ondan önce yazılan işler bir zamanlamaya geri izlenemiyordu.
    $col = WDB::query("SHOW COLUMNS FROM `AuroraBackup_jobs` LIKE 'schedule_id'");
    if (!$col || !WDB::getAssoc($col))
        WDB::exec('ALTER TABLE `AuroraBackup_jobs` ADD `schedule_id` INT UNSIGNED NOT NULL DEFAULT 0 AFTER `user_id`');
}

Oluşturmayı ve kolon onarımını ayrı dallarda tutun; oluşturma dalındaki tohumlama eski tabloda düşer.

Changelog'u yazın

Diyalog notları başlıklar altında gruplar, her satır dört tipten birini taşır; bilinmeyen tip en sonda görünür.

yayıncının gönderdiği ve sihirbazın bastığı biçim
[
  {"type": "features",     "text": "Scheduled jobs can now target a second storage account."},
  {"type": "improvements", "text": "Listing a bucket with many objects no longer times out."},
  {"type": "security",     "text": "Restore tokens are now single use."},
  {"type": "fixes",        "text": "A job cancelled during upload left a partial archive behind."}
]

Referans

Manifest alanları

AlanZorunluKural
typeher zamanwstore ya da marketplace; başkası "yönetilmiyor" demektir
idmarketplaceSayısal ilan kimliği; dizin adları benzersiz değildir
namestoreÜrün anahtarı; boşsa manifest'in tamamı reddedilir
versionher zamanKurulu sürüm ve karşılaştırılan tek şey
last_updatedhayırOperatöre gösterilir, karara girmez

Güncelleyici arayüzü

imzalar
// diskte olanı okuma
public static function manifest(string $dir): array;
public static function version(string $type, string $key): string;
public static function normalize(string $version): string;
public static function installed(bool $activeOnly = true): array;
public static function dir(array $item): string;

// yayıncıya sorma
public static function releases(array $items): array;
public static function pending(bool $activeOnly = true): array;
public static function issue(string $source, string $ident): array;
public static function notes(array $changelog): array;
public static function is_newer(string $remote, string $local): bool;

// tek bir güncellemeyi çalıştırma
public static function token(string $source, string $ident, string $version): string;
public static function begin(string $source, string $ident, string $version): array;
public static function job(string $token): array;
public static function step(string $token, string $step): array;
public static function abandon(string $token): void;
public static function write_manifest(string $dir, array $manifest): bool;

// STEPS sabit sıradır: download, extract, apply, finish.
// PRESERVED, apply adımının üzerine yazmayı reddettiği dosya adlarının listesidir: config.php.
ModuleUpdater::installed() Yönetilen her dizin: kind, type, key, dir, active ve ident.
ModuleUpdater::pending() Kurulu kayda ek olarak release, product, developer, changelog, available.
ModuleUpdater::manifest() Anlam veremediğine boş dizi döner; paketinizi denetlemek için kullanın.
ModuleUpdater::step() Adlı tek adımı çalıştırır ve aynı adım için tekrar çağrılabilir.
ModuleUpdater::token() Kaynak, kimlik ve sürümden türer; tekrar deneme yarım işi sürdürür.

Uygulama ne yapar

Önce geri alma kopyası alınır Tek bir dosya yazılmadan önce hedef dizinin tamamı bir kenara kopyalanır.
Dosyalar birleştirilir, değiştirilmez Paket ağacı hedefin üstüne kopyalanır; eksik dizinler oluşturulur.
config.php varsa atlanır Operatör ayarları korunur; yeni bir bileşenin kendi config'i yine kurulur.
Hiçbir şey silinmez Paketten çıkardığınız dosya diskte kalır: silme listesi yoktur.
Manifest en son yazılır Yarıda ölen bir güncelleme bitmiş gibi görünmez.

Hata kodları

Her adım cümle yerine çıplak bir kod fırlatır, böylece panel onu çevirebilir.

KodNeredenGenellikle ne demek
not_managedbegin, applyOkunabilir manifest yok: elle kurulmuş ya da bozuk
already_currentbeginSunulan sürüm yeni değil; genellikle yeniden kullanılmış numara
download_faileddownloadİmzalı adres hiçbir şey döndürmedi
zip_unavailableextractSunucuda ZipArchive yok
archive_unreadableextractArşiv açılmadı; en sık sebebi iç içe arşiv
package_mismatchextract, applyHiçbir düzen beklenen sınıf dosyasını taşımıyordu
install_failedapplyKopyalama başarısız; geri alma kopyası yerine kondu

Örnek

Tek bir yayın: değişen iki dosyadan sistemin geri okuduğuna kadar.

manifest, önce ve sonra
// müşterinin diskinde olan
{"type": "marketplace", "id": 42, "version": "1.1.0", "last_updated": "2026-05-14"}

// 1.2.0 paketine koyduğunuz
{"type": "marketplace", "id": 42, "version": "1.2.0", "last_updated": "2026-08-03"}
arşiv
AuroraBackup-1.2.0.zip
 └─ AuroraBackup/                 # tam olarak modül anahtarı
     ├─ AuroraBackup.php          # çıkarıcının aradığı dosya
     ├─ manifest.json             # sürüm 1.2.0
     ├─ config.php                # gönderilir, ama zaten varsa atlanır
     ├─ lang/
     │   └─ en.php                # bir dizin, asla düz bir lang.php değil
     └─ views/
         ├─ index.php
         └─ schedules.php         # 1.2.0'da yeni, düz kopya olarak gelir
yayınlamadan önce kendi paketinizi denetleme
<?php
// temp/_manifest-probe.php  :  paketin açılmış bir kopyası üzerinde çalıştırın
require dirname(__DIR__) . '/bootstrap.php';

$dir = MODULE_DIR . 'Addons' . DS . 'AuroraBackup';

$manifest = ModuleUpdater::manifest($dir);

// Boş olması, o dizine hiçbir zaman güncelleme sunulmayacağı demektir: bilinmeyen tip,
// eksik sürüm ya da id'siz bir marketplace kaydı.
if (!$manifest) exit("not managed: fix manifest.json\n");

$installed = (string) ($manifest['version'] ?? '');

echo 'reads as: ', $manifest['type'], ' / ', $installed, "\n";
echo ModuleUpdater::is_newer('1.2.0', $installed) ? "1.2.0 would be offered\n" : "1.2.0 would NOT be offered\n";
başarılı uygulamadan sonra sistemin geri okuduğu
{
    "type": "marketplace",
    "id": 42,
    "version": "1.2.0",
    "last_updated": "2026-08-03"
}

Kimlik alanları yeniden türetilmez, orada zaten olandan taşınır.

Tuzaklar

config.php'deki sürümü yükseltmek bir şey değiştirmez

Güncelleme o dosyaya hiç yazmaz, oradaki numara ilk kurulumdaki değerde donar.

Yanlış seviyeyi ziplemek

Kökünde sınıf dosyasını taşıyan arşiv de, modül klasörünü taşıyan da çalışır. Sürüm adlı bir klasör ya da iç içe arşiv package_mismatch ile durur.

Enable'daki migration yükseltmeyi atlar

Enable bir kez olur ve yükselten her müşteri bunu çoktan yapmıştır, o yüzden oraya bağlanan bir değişiklik mevcut kurulumları atlar.

Dosyayı paketten çıkarmak müşteriden çıkarmaz

Eski dosya diskte ve yüklenebilir kalır; gitmesi gerekiyorsa yerine gelen sürüm onu etkisizleştirmelidir.

Yayınlanmış bir sürüm numarası düzeltilemez

Yanlış numara, yerinde düzenlenerek değil, yayın silinip yeniden yayınlanarak düzeltilir.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.