IlmHamroh
JavaScript Full-stack/32-qism. Professional Git va jamoada ishlash19/19-dars27 daqiqa
Mundarija (42)

Open source: hissa qo'shish va litsenziyalar — MIT, Apache-2.0, GPL, AGPL

Qisqacha: Open source — kodi ochiq va litsenziyasi foydalanish, o'zgartirish va tarqatishga ruxsat beradigan dastur. Unga hissa qo'shish tartibi: good first issue tanlash, CONTRIBUTING.md ni o'qish, issue'da gaplashish, kichik PR yuborish va review'ga sabr bilan javob berish. Litsenziya — kodingizdan boshqalar nima qila olishini aytadigan shartnoma. MIT va Apache-2.0 deyarli hamma narsaga ruxsat beradi, GPL hosila dasturni ham ochiq qilishni talab qiladi, AGPL esa tarmoq orqali xizmat ko'rsatishni ham tarqatish deb hisoblaydi. Kanonda kurs loyihasiga MIT LICENSE qo'shildi (PR #19) va hissa qo'shuvchi oqimi PR #20 da takrorlandi. Bu dars bilan 32-qism tugaydi.

Diqqat: Bu darsdagi litsenziya ma'lumotlari — dasturchi uchun umumiy tushuncha, yuridik maslahat emas. Pul, mijoz yoki kompaniya kodi bilan bog'liq qaror bo'lsa — huquqshunos bilan maslahatlashing.

Bu darsda

  • Hissa qo'shish uchun loyiha va issue tanlaysiz, maintainer bilan to'g'ri gaplashasiz.
  • DCO (git commit -s) va CLA farqini tushuntirasiz.
  • MIT, Apache-2.0, GPL-3.0, AGPL-3.0 va MPL-2.0 shartlarini solishtirasiz.
  • Bog'liqliklar litsenziyasini tekshirasiz va muvofiqlik qoidasini qo'llaysiz.
  • Kurs loyihasiga LICENSE qo'shasiz va birinchi haqiqiy open source PR'ingizni rejalashtirasiz.

Oldin bilishingiz kerak: GitHub asoslari: repo, README, LICENSE, Fork va upstream, Yaxshi PR tayyorlash, Code review berish va olish.

1. Nega bu kerak?

vazifalar-api ning package-lock.json faylida 876 ta paket bor. Loyiha ulardan faqat 73 tasini o'zi tanlagan (package.json da 43 ta asosiy va 30 ta dev bog'liqlik), qolganlari — ularning bog'liqliklari. Bu paketlarni minglab begona odamlar yozgan va ularning hech biri sizdan pul so'ramagan. Zamonaviy dastur — asosan boshqalar yozgan ochiq kod ustidagi yupqa qatlam.

Bundan ikki savol chiqadi. Birinchisi: qaytarish. Siz ishlatgan kutubxonada xato topdingiz yoki hujjatda imlo xatosi bor. Uni tuzatish — eng yaxshi o'rganish va ko'rinadigan portfolio. Haqiqiy loyihadagi birlashtirilgan PR rezyumedagi "jamoada ishlay olaman" degan gapdan kuchliroq.

Ikkinchisi: huquq. Bu paketlardan foydalanishga kim ruxsat berdi? Ruxsat — har paketdagi litsenziya. Ba'zi litsenziyalar "nima qilsangiz qiling" deydi, ba'zilari "kodingizni ham ochishingiz shart" deydi. Farqni bilmagan dasturchi kompaniyani qiyin ahvolga solib qo'yishi mumkin.

Hayotiy o'xshatish: mahalla hashari. Hamma ko'chani birga tozalaydi, hamma foydasini ko'radi. Lekin hasharning ham qoidasi bor: qayerdan boshlanadi, kim nimaga mas'ul, asbobni kim beradi. Open source — dasturchilarning dunyo miqyosidagi hashari. CONTRIBUTING.md — uning qoidasi, litsenziya — "asbobdan qanday foydalanish" shartnomasi.

2. Open source nima

2.1 Ochiq kod ≠ ochiq repo

GitHub asoslari darsida ko'rgansiz: litsenziyasiz public repo — ochiq emas. Kodni ko'rish mumkin, lekin standart mualliflik huquqi amal qiladi. Uni nusxalab tarqatish yoki undan o'z ishini yasash mumkin emas.

Open source (ochiq kodli dastur) — litsenziyasi foydalanish, o'rganish, o'zgartirish va tarqatishga ruxsat beradigan dastur. Qaysi litsenziya "open source" deb hisoblanishini Open Source Initiative (OSI) o'zining Open Source Definition mezonlari bilan belgilaydi (opensource.org, 2026-11-04). Unda 10 ta mezon bor. Masalan, oltinchisi — "faoliyat sohasiga qarab kamsitmaslik": litsenziya dasturni biror sohada ishlatishni taqiqlamasligi kerak. Shuning uchun "faqat notijorat foydalanish" degan shart bu mezonlarga zid. Shunday litsenziyali kod ochiq ko'rinsa ham, open source emas — uni "source-available" deyishadi.

2.2 Hissa — faqat kod emas

Hissa (contribution) — loyihaga foydali har qanday qo'shimcha. Birinchi hissa ko'pincha koddan boshlanmaydi:

  • hujjatdagi xato yoki eskirgan buyruqni tuzatish;
  • xatoni takrorlanadigan qilib, aniq issue yozish;
  • boshqalarning issue'sini sinab ko'rib, "menda ham shunday, versiya X" deb yozish;
  • tarjima, misol, test qo'shish.

Hujjat tuzatishi "jiddiy emas" degan fikr noto'g'ri. U loyiha jarayonini — CONTRIBUTING, CI, review, merge — to'liq o'tadi, ya'ni kod PR'idan oldin eng yaxshi mashq.

3. Hissa qo'shish oqimi

3.1 Butun yo'l bitta rasmda

flowchart TD
  A["Loyiha tanlash"] --> B["good first issue"]
  B --> C["CONTRIBUTING o'qish"]
  C --> D["Issue'da yozish"]
  D --> E["Fork, branch, commit -s"]
  E --> F["Kichik PR"]
  F --> G{"Review"}
  G -->|o'zgartirish| E
  G -->|tasdiq| H["Merge"]

Diagrammadagi siklga e'tibor bering: review'dan keyin yana commit — bu normal holat, muvaffaqiyatsizlik emas. Har bosqichni ko'rib chiqamiz.

3.2 Loyiha va issue tanlash

Birinchi hissa uchun eng yaxshi loyiha — o'zingiz ishlatadigan loyiha. Uning qanday ishlashini bilasiz, xatoni o'zingiz ko'rgansiz, hujjatdagi kamchilik sizni o'zi bezovta qilgan.

Maintainer'lar yangi kelganlar uchun mos issue'larni maxsus label bilan belgilaydi. GitHub hujjati shunday deydi: good first issue label'i repodagi issue'larni hissa qo'shish imkoniyati sifatida ajratadi, GitHub esa eng qulaylarini turli joylarda ko'rsatadi (docs.github.com, 2026-11-04). Qidiruvda shunday yozasiz (sinalmagan, 2026-11):

text
is:issue is:open label:"good first issue" language:JavaScript

Issue tanlashda tekshiriladigan narsalar:

Belgi Yaxshi Xavotirli
Oxirgi commit bir necha kun yoki hafta oldin bir yildan ko'p
PR'larga javob kunlar ichida oylab javobsiz
Issue aniq, qabul mezoni bor "hammasini qayta yozish"
Kimdir oldi hech kim yozmagan "men qilyapman" degan izoh bor

Oxirgi qator muhim: kimdir "men olaman" deb yozgan bo'lsa, ikkinchi PR — vaqt isrofi va odobsizlik. Avval so'rang.

Kurs loyihasida ham shunday issue bor edi — Jamoadagi yangi loyihaga kirish darsidagi #8. Uning tanasi yaxshi good first issue namunasi (kanon matnidan, qatorlar bo'lindi; asl matndagi bo'lim raqami iqtibosda bo'lim nomi bilan almashtirildi):

markdown
**Qayerdan boshlash:** `vazifalar-api/src/ai/chidamli.ts`
(`holatModel()`), `vazifalar-api/src/kuzatuv/metrikalar.ts`
(`fonXatolari` — modul darajasidagi metrika namunasi),
`docs/ARXITEKTURA.md`, "Birinchi vazifa: qanday boshlash" bo'limi.

**Qabul mezonlari:**
- [ ] `/metrics` da `ai_breaker_holati{model="…"}`
  (0 — yopiq, 1 — yarim, 2 — ochiq)
- [ ] test: breaker ochilganda qiymat 2
- [ ] `npm run check` yashil

"Qayerdan boshlash" — yangi odamga eng qimmat yordam. Qabul mezonlari esa oldingi darsdagidek tekshiriladigan.

3.3 CONTRIBUTING.md va birinchi xabar

PR'dan oldin loyiha qoidalarini o'qing: CONTRIBUTING.md, CODE_OF_CONDUCT.md, PR shabloni. Ularda branch nomi, commit formati, testni qanday yurgizish va imzo talabi yoziladi. Xulq-atvor kodeksi (code of conduct) — muloqot odobi qoidalari. Kurs loyihasida u yo'q, lekin katta loyihalarda ko'p uchraydi. CONTRIBUTING.md va PR shablonini esa Yaxshi PR tayyorlash va Texnik yozish darslarida o'zingiz yozgansiz. Endi ularni begona hissa qo'shuvchi ko'zi bilan o'qiysiz.

Keyin issue'ga qisqa xabar yozing. Yaxshi xabar uch narsani aytadi: nima qilmoqchisiz, qanday qilmoqchisiz va savolingiz. Inglizcha, chunki ko'p loyihalar shu tilda (Ingliz tilida yozish darsidagi buyruq mayli):

text
Hi! I'd like to work on this. My plan: add an
`ai_breaker_holati` gauge in metrikalar.ts and update it
from holatModel(). Should the metric be per model or per
provider? I can open a draft PR by Friday.

Bu xabarda reja bor, aniq savol bor va muddat bor. "Can I work on this?" deb qoldirish ham mumkin, lekin reja bilan maintainer darhol yo'naltira oladi.

3.4 Kichik PR va review

Birinchi PR qanchalik kichik bo'lsa, shunchalik tez merge bo'ladi. Maintainer — ko'pincha bo'sh vaqtida ishlaydigan ko'ngilli. 30 qatorli PR'ni bir kunda ko'rib chiqadi, 800 qatorlisini oylab ochmaydi.

Review'da ikki odat yordam beradi. Birinchisi: har izohga javob bering — "tuzatdim, abc123" yoki "rozi emasman, sababi…". Ikkinchisi: sabr. Bir hafta javob bo'lmasa, bitta muloyim eslatma yetadi. Har kuni yozish — bosim. Code review darsidagi Conventional Comments bu yerda ham ishlaydi.

Ba'zi loyihalar AI vositalari bilan yozilgan PR'lar bo'yicha alohida qoida qo'yadi: oshkor qilishni talab qiladi yoki cheklaydi. Qoida CONTRIBUTING.md da bo'ladi. O'zingiz tushunmagan va tekshirmagan kodni yubormang — review'dagi savolga javob bera olmaysiz.

Tekshirib ko'ring: Siz yoqtirgan kutubxonada good first issue topdingiz. Ostida uch hafta oldin "I'll take this" degan izoh bor, PR esa yo'q. Nima qilasiz?

Javob

Darhol PR ochmang. Issue'ga muloyim savol yozing: "Are you still working on this? If not, I'd be happy to pick it up." Bir necha kun javob bo'lmasa, maintainer'dan so'rang. Kimdir ishni olib qo'ygan bo'lsa, unga hurmat — loyiha madaniyatining bir qismi. Javob kelmasa, maintainer issue'ni sizga beradi.

4. Kim yozgani: DCO va CLA

4.1 Nega loyihaga bu kerak

Siz PR yubordingiz, u merge bo'ldi. Endi loyihada sizning kodingiz bor. Loyiha qanday ishonch hosil qiladi: bu kodni yuborishga haqqingiz bormi? Balki uni ish joyingizdagi yopiq loyihadan ko'chirgandirsiz? Buning uchun ikki usul ishlatiladi.

CLA (Contributor License Agreement) — hissa qo'shuvchi imzolaydigan alohida shartnoma: odatda u loyiha egasiga hissangizdan keng foydalanish huquqini beradi. Ko'pincha kompaniya loyihalarida bo'ladi, birinchi PR'da bot imzolashni so'raydi (sinalmagan, 2026-11).

DCO (Developer Certificate of Origin) — yengilroq usul. Shartnoma o'rniga har commit oxiriga bitta qator qo'shiladi. Bu qator bilan siz DCO 1.1 matnini tasdiqlaysiz (developercertificate.org, 2026-11-04). Uning birinchi uch bandi — "yoki" bilan: hissani o'zingiz yaratgansiz, yoki u ochiq litsenziyali ishga asoslangan, yoki uni sizga shunday tasdiqlagan boshqa odam bergan. Har holda uni fayldagi litsenziya ostida yuborishga haqqingiz bor. To'rtinchi band doim amal qiladi: hissa va imzoingiz ommaviy ekanini, yozuv muddatsiz saqlanishini qabul qilasiz.

4.2 git commit -s

DCO qatori uchun Git'da tayyor bayroq bor — -s (--signoff). Biz bo'sh temp repoda ishga tushirdik:

bash
git commit -q -s -m "docs: README imlosi"
git log -1 --format=%B
text
docs: README imlosi

Signed-off-by: Aziz Karimov <aziz@example.com>

Xabar oxiriga trailer (xabar dumi) qo'shildi: Signed-off-by: va user.name / user.email dagi ism. Uni skriptda ham o'qish mumkin:

bash
F='%(trailers:key=Signed-off-by,valueonly,separator=)'
git log -2 --format="%h %s | $F"
text
d0fadc7 fix: imlo | 
1d992ab docs: README imlosi | Aziz Karimov <aziz@example.com>

Ikkinchi commit -s siz qilingan — qator bo'sh. DCO talab qiladigan loyihalarda shunday commit'li PR'ni bot to'xtatadi va "sign off" qilishni so'raydi.

Diqqat: -s va -S — ikki xil narsa. Kichik -s — DCO qatori: "huquqim bor" degan matn, kriptografiya yo'q. Katta -S — Commit imzolash darsidagi kriptografik imzo: "commitni haqiqatan men yaratdim". Ba'zi loyihalar ikkalasini ham talab qiladi.

Unutib qo'ygan commitga keyin git commit --amend -s --no-edit bilan qo'shish mumkin. Bir nechta commit bo'lsa — git rebase --signoff main (Git 2.54.0 da sinadik).

5. Litsenziyalar

5.1 Ikki oila

Litsenziyalarni ikki katta oilaga ajratishadi:

  • Ruxsat beruvchi (permissive): MIT, ISC, BSD, Apache-2.0. "Nima qilsangiz qiling — faqat muallif nomi va litsenziya matnini saqlang." Kodni yopiq mahsulotga ham qo'shish mumkin.
  • Kopileft (copyleft): GPL, AGPL. "Kodimni o'zgartirib tarqatsangiz — o'zgargan dastur ham shu litsenziya ostida ochiq bo'lsin." Erkinlik keyingi foydalanuvchilarga ham o'tadi.

O'rtada zaif kopileft bor: MPL-2.0, LGPL. Shart butun dasturga emas, faqat litsenziyali fayllarning o'ziga yoki kutubxonaga tegishli.

5.2 Asosiy beshtasi

choosealicense.com (uni GitHub yuritadi) har litsenziyani ruxsat, shart va cheklov bo'yicha tavsiflaydi (2026-11-04). Shartlar ustuni eng muhim:

Litsenziya Asosiy shart Patent
MIT mualliflik va litsenziya matni saqlansin aytilmagan
Apache-2.0 + o'zgarishlarni bildirish aniq ruxsat
MPL-2.0 o'zgargan fayllar ochiq aniq ruxsat
GPL-3.0 hosila ish ham GPL, kodi ochiq aniq ruxsat
AGPL-3.0 GPL + tarmoqda foydalanish ham tarqatish aniq ruxsat

Oxirgi qatorni batafsilroq ko'raylik. GPL faqat dastur tarqatilganda ishlaydi: foydalanuvchiga fayl yoki ilova berdingiz. Server'da ishlaydigan backend esa tarqatilmaydi — foydalanuvchi faqat HTTP so'rov yuboradi. Shuning uchun GPL'li kodni o'zgartirib, SaaS sifatida ishlatsangiz, kodni ochish shart emas. AGPL aynan shu "teshik"ni yopadi: o'zgargan dastur tarmoq orqali xizmat ko'rsatsa, foydalanuvchilarga uning to'liq manba kodi berilishi kerak.

vazifalar-api — aynan tarmoq xizmati. Shuning uchun AGPL'li kutubxonani o'zgartirib ichiga qo'shish loyihani AGPL shartlariga bog'laydi.

5.3 Kanon tanlovi: nega MIT

Kanon PR #19 tavsifida tanlov sababi yozilgan (matn aynan, qatorlar bo'lindi):

markdown
Kurs loyihasi: hamma o'qisin, nusxa olsin, o'z loyihasida
ishlatsin; sharti — mualliflik va ruxsat matni saqlansin.
Apache-2.0 (patent bandi) — kompaniya kodi uchun yaxshiroq,
lekin matni uzun; GPL/AGPL — hosila ishlarni ham ochiq qilishni
talab qiladi (AGPL — tarmoq orqali xizmat ko'rsatishda ham),
SaaS backend uchun boshqalarning foydalanishini cheklaydi.

Bu — qaror yozuvi: tanlangan variant, rad etilganlar va har birining sababi. Muloqot darsidagi ADR g'oyasi kichik shaklda.

Tekshirib ko'ring: Nodira o'z startapi uchun ochiq kodli backend yozmoqchi. Raqobatchi uning kodini olib, o'zgartirib, yopiq SaaS sifatida sotishini istamaydi. MIT, GPL-3.0 yoki AGPL-3.0 — qaysi biri bu maqsadga mos va nega?

Javob

AGPL-3.0. MIT raqobatchiga hamma narsaga ruxsat beradi. GPL-3.0 dastur tarqatilganda ishlaydi, SaaS esa tarqatilmaydi — raqobatchi o'zgarishlarini yashira oladi. AGPL tarmoqda foydalanishni ham hisobga oladi: raqobatchi o'zgargan kodni ochishi shart. Narxi: ko'p kompaniyalar AGPL kodini ichki siyosat bo'yicha umuman ishlatmaydi. Demak, foydalanuvchilar soni ham kamayishi mumkin.

6. Muvofiqlik: bog'liqliklar nimani talab qiladi

6.1 Qoida — bir yo'nalishli

Loyihangizga boshqa litsenziyali kod qo'shsangiz, ikkala litsenziyaning shartlari birga bajarilishi kerak. Buni litsenziya muvofiqligi (compatibility) deyishadi. Amaliy qoidalar:

  • ruxsat beruvchi kod kopileft loyihaga kira oladi: MIT kodini GPL loyihaga qo'shish mumkin;
  • teskarisi — yo'q: GPL kodini MIT loyihaga qo'shsangiz, birlashma GPL shartlariga bo'ysunadi;
  • versiyalar ham muhim. Apache Software Foundation yozadi: Apache-2.0 GPLv3 bilan mos, lekin FSF uni hech qachon GPLv2 bilan mos deb hisoblamagan — patent bandlari tufayli (apache.org, 2026-11-04).

Bu qoidalarni 2-mashqda funksiyaga aylantirasiz.

6.2 Kanon tajribasi: 876 paket

Kurs loyihasining bog'liqliklarini tekshiramiz. package-lock.json da har paket yozuvida license maydoni va dev belgisi bor. Biz kichik skript yozdik va loyihaning 32-qism yakunidagi lock fayli ustida ishga tushirdik:

bash
node litsenziyalar.mjs package-lock.json

Natija (2026-11-04):

text
prod: 499 paket
  MIT            357
  Apache-2.0     71
  ISC            35
  BSD-3-Clause   18
  BSD-2-Clause   6
  (yo'q)         2
  Unlicense      2
  0BSD           2
  MIT and ISC    1
  Python-2.0     1
  EPL-2.0        1
  BlueOak-1.0.0  1
  MIT-0          1
  MPL-2.0        1
dev: 377 paket
  MIT            312
  Apache-2.0     19
  ISC            15
  MPL-2.0        12
  BSD-2-Clause   7
  BSD-3-Clause   4
  BlueOak-1.0.0  4
  (yo'q)         3
  Unlicense      1
prod, license maydonisiz: busboy, streamsearch

Uni o'qiymiz:

  • Ko'pchilik ruxsat beruvchi. Prodakshn paketlarining 357 tasi MIT, 71 tasi Apache-2.0. GPL yoki AGPL — bitta ham yo'q. MIT loyiha uchun bu toza manzara.
  • MPL-2.0 prodakshnda — bitta. Biz qaradik: bu web-push, push bildirishnomalar uchun loyihaning o'zi tanlagan paket. MPL fayl darajasida ishlaydi: paketni o'zgartirmay ishlatish MIT loyihaga to'sqinlik qilmaydi. Uning fayllarini o'zgartirsangiz, o'sha fayllar MPL ostida ochiq qolishi kerak.
  • "(yo'q)" — xavf emas, ma'lumot yo'qligi. busboy — fayl yuklashdagi asosiy paket. Biz uning package.json ini ochdik va eski shaklni topdik: "licenses": [ { "type": "MIT", … } ]. npm hujjati bu shaklni eskirgan deb ataydi va SPDX satrini tavsiya qiladi: "license": "MIT" (docs.npmjs.com, 2026-11-04). Lock faylga faqat yangi shakl tushadi, shuning uchun avtomatik vosita "noma'lum" ko'rsatdi.
  • Kam uchraydiganlar. EPL-2.0 (elkjs), Python-2.0 (argparse), BlueOak-1.0.0 (minimatch). Ularni lock fayldagi dependencies bo'yicha kuzatdik: elkjs — Prisma Studio paketidan, argparse — js-yaml dan. Bularni bir marta qo'lda tekshirish kerak — avtomatik ro'yxatga ishonib qolmang.

MIT and ISC kabi yozuvlar — SPDX ifodasi. SPDX — litsenziyalarning standart qisqa nomlari ro'yxati (MIT, Apache-2.0, GPL-3.0-only). AND — ikkala shart ham, OR — tanlash mumkin (ro'yxat — spdx.org, 3.29.0 versiyasi, 2026-11-04 da ochildi; AND/OR qoidasi SPDX spetsifikatsiyasidan — sinalmagan, 2026-11).

Maslahat: Kompaniyalarda bunday tekshiruv CI'da avtomatik yuradi: "ruxsat etilgan litsenziyalar ro'yxati"dan tashqari paket qo'shilsa, PR to'xtaydi. Tayyor vositalar ham bor, lekin ular ham license maydoniga tayanadi — busboy kabi holatlarni qo'lda ko'rib chiqish baribir kerak.

7. Loyiha qadami: MIT LICENSE va birinchi hissa

7.1 Topilma qayerdan keldi

Code review berish va olish darsida README PR'i (#15) review'ida haqiqiy kamchilik topilgan edi. Kanon review izohi (qatorlar bo'lindi, matn aynan):

markdown
**muammo:** `package.json` da `"license": "MIT"`, lekin repoda
(vazifalar-api ichida) `LICENSE` fayli YO'Q. Litsenziya matnisiz
"MIT" deyish yetarli emas — MIT'ning yagona sharti: mualliflik
huquqi va ruxsat matni nusxalarda saqlansin.

Muallif rozi bo'ldi va ishni alohida issue'ga chiqardi — #16: "docs: vazifalar-api uchun LICENSE fayli (MIT)". Uning qabul mezoni: LICENSE (MIT matni, yil va egasi), README va CONTRIBUTING'da havola.

7.2 Fayl

Matnni qo'lda yozmang. GitHub asoslari darsidagi "Choose a license template" tugmasi yoki SPDX ro'yxatidagi rasmiy matn ishlatiladi. Kanon fayli — o'zgartiriladigan yagona qator egasining nomi:

text
MIT License

Copyright (c) 2026 Ismingiz Familiyangiz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Litsenziya matni o'zgartirilmaydi, shuning uchun telefon uchun qatorlarni bo'lmadik. Kanonda egasi o'rnida "vazifalar-api mualliflari" yozilgan — bu ham to'g'ri: ko'p mualliflik loyihalar shunday qiladi. O'z repo'ngizda — ismingiz.

Ikkinchi qism — kafolat yo'qligi: dastur "boricha" (as is) beriladi, muallif zarar uchun javob bermaydi. MIT'ning bir sharti va bir himoyasi bor, xolos.

Matn haqiqatan rasmiy matnmi? Biz tekshirdik: npm'dagi spdx-license-list 6.12.0 paketidan SPDX MIT matnini oldik va kanon fayli bilan solishtirdik. Qatorlar boshqacha bo'lingan, shuning uchun bo'shliqlarni bittaga keltirdik:

bash
node mit-solishtir.mjs LICENSE MIT.json
text
sarlavha (fayl): MIT License Copyright (c) 2026 vazifalar-api mualliflari 
sarlavha (SPDX): MIT License Copyright (c) <year> <copyright holders> 
ruxsat va kafolat matni bir xil: true

Faqat yil va egasi farq qiladi — shu ikkisini to'ldirish kerak.

7.3 README va CONTRIBUTING

README'dagi "Litsenziya" bo'limi PR #15 dagi taklif (```suggestion) bo'yicha o'zgardi: MIT. o'rniga MIT — [LICENSE](LICENSE). CONTRIBUTING'ga esa yangi bo'lim qo'shildi (matn aynan, qatorlar bo'lindi):

markdown
## Litsenziya

Hissa qo'shganingiz loyiha litsenziyasi (MIT, [LICENSE](LICENSE))
ostida tarqatilishiga rozilik bildiradi (inbound = outbound). Begona
koddan nusxa olsangiz — uning litsenziyasi MIT bilan mos bo'lsin
(MIT, BSD, Apache-2.0 — ha; GPL/AGPL kodini qo'shish butun
loyihaning litsenziya shartlarini o'zgartiradi — avval issue'da
muhokama).

Inbound = outbound — "kiruvchi hissa chiquvchi litsenziya bilan bir xil". CLA'siz loyihalarda bu oddiy kelishuv: PR yuborgan odam hissasi loyiha litsenziyasi ostida tarqatilishiga rozi.

7.4 Commit va PR

bash
git switch main
git pull
git switch -c docs/litsenziya
git add LICENSE README.md CONTRIBUTING.md
git commit -m "docs: vazifalar-api uchun MIT LICENSE va hissa litsenziyasi"
git push -u origin docs/litsenziya

PR tavsifida — Closes #16. Bu safar Closes, Refs emas: issue to'liq yopiladi. Kanonda PR #19 squash bilan qo'shildi va #16 avtomatik yopildi:

text
#19 MERGED a9550ae

Bosqich tekshiruvida bitta test yiqildi: auth.test dagi vaqt o'lchovi (timing) testi. U noma'lum email va mavjud email uchun javob vaqtlari yaqin bo'lishini tekshiradi (farq ≤ 20 ms yoki ≤ 15 %). Bu safar mavjud email uchun mediana 303.4 ms, noma'lum uchun 257.4 ms chiqdi: farq 46 ms, ruxsat esa 45.5 ms (303.4 ning 15 %i) — chegaradan biroz tashqari. Hujjat PR'i kodga tegmagan, shuning uchun sabab boshqa: bu test Nozik xatolar darsidagi beqaror (flaky) test turidan, Test arxitekturasi va CI darsidan ma'lum. Qayta yurgizishda 346 ta o'tdi, 1 ta o'tkazib yuborildi. Kanon PR tavsifida buni yashirmadi va testni barqarorlashtirishni keyingi qismlar ro'yxatiga yozdi.

7.5 "Boshqa loyihaga 1 ta PR": kanon nima qildi

32-qism rejasining oxirgi bandi — boshqa loyihaga PR. Kurs kanoni begona repolarga yozmaydi. Shuning uchun hissa qo'shuvchi oqimi kurs sinov reposining boshqa qismida takrorlandi: 07-qismdagi sayt/ portfoliosi README'siga izoh. Fork sinalmadi — bitta akkaunt bor edi va yangi repo yaratilmadi. O'rniga Fork va upstream darsidagi oqim klon bilan ko'rsatildi. Kanon chiqishi (repo manzili login/vazifalar-api ga almashtirildi):

bash
git clone -q https://github.com/login/vazifalar-api.git hissa-klon
cd hissa-klon
git remote rename origin upstream
git remote -v
git fetch -q upstream
git switch -q -c docs/sinov-repo-izohi upstream/main
git log --oneline -1
text
upstream	https://github.com/login/vazifalar-api.git (fetch)
upstream	https://github.com/login/vazifalar-api.git (push)
a9550ae docs: vazifalar-api uchun MIT LICENSE va hissa litsenziyasi (#19)

Haqiqiy fork'da yana bir qadam bo'ladi: git remote add origin <sizning-fork> va push origin ga. Kanonda push upstream ga ketdi, chunki fork yo'q edi. PR #20 ochildi. Merge buyrug'i esa yana GitHub nosozligiga duch keldi:

text
non-200 OK status code: 502 Bad Gateway body: "<html>\r\n<head><title>502 Bad Gateway</title></head>\r\n<body>\r\n<center><h1>502 Bad Gateway</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n"
#20 MERGED 7f8f2d4

Birinchi qatorda xato, ikkinchisida — MERGED. Merge bajarilgan, xato javobning o'zi yo'lda yo'qolgan. Jamoa workflow'lari darsidagi qoida yana bir bor: 502 — "bajarilmadi" degani emas, holatni tekshiring.

7.6 Sizning birinchi haqiqiy PR'ingiz

Kanon begona repoga yoza olmadi, siz esa yoza olasiz — va bu qismning eng muhim amaliy topshirig'i shu. Loyihani o'zingiz tanlang. Yo'riqnoma:

  1. Loyiha: shu kursda ishlatgan kutubxonalardan biri (Express, Prisma, Vitest, NestJS va boshqalar) yoki kichikroq paket. Oxirgi commit yaqinda, PR'larga javob beriladi.
  2. Issue: good first issue yoki hujjatdagi o'zingiz topgan xato. Hech kim olmagan.
  3. Qoidalar: CONTRIBUTING.md, litsenziya, CLA yoki DCO talabi.
  4. Xabar: issue'ga reja va savol bilan yozing, javobni kuting.
  5. Ish: fork, upstream qo'shish, upstream/main dan branch, kichik commit (-s talab qilinsa).
  6. PR: shablon bo'yicha tavsif, Closes #N, testlar natijasi.
  7. Review: har izohga javob, sabr.

PR havolasini portfolio README'ingizga yozing — merge bo'lmagan bo'lsa ham. Ochiq PR ham sizning kod yozishingizni, muloqotingizni va review'ga munosabatingizni ko'rsatadi. Repoga nima tegishini bilish uchun 3-mashq butun oqimni lokal o'xshatishda o'tkazadi.

8. Ko'p uchraydigan xatolar

8.1 Litsenziyasiz repo — "ochiq"

Public, lekin LICENSE yo'q — hech kim qonuniy foydalana olmaydi. Davosi: repo ochilgan kuni LICENSE qo'shing.

8.2 package.json da bor, faylda yo'q

Kanon xatosi («Topilma qayerdan keldi» bo'limi). Davosi: license maydoni ham, LICENSE fayli ham bo'lsin.

8.3 Litsenziya matnini "tahrirlash"

"Biroz qisqartirdim", "o'zbekchaga tarjima qildim" — endi bu MIT emas, noma'lum litsenziya. Davosi: rasmiy matn, faqat yil va egasi o'zgaradi.

8.4 GPL kodini nusxalash

Stack Overflow yoki GitHub'dan "kichik funksiya"ni ko'chirdingiz — u GPL loyihadan. Davosi: begona koddan oldin uning litsenziyasini tekshiring, kerak bo'lsa issue'da muhokama qiling (kanon CONTRIBUTING qoidasi).

8.5 Katta birinchi PR

"Butun modulni qayta yozdim, 1 200 qator" — maintainer ochmaydi. Davosi: avval issue'da kelishing, keyin kichik qadamlar.

8.6 DCO qatori yo'q

Bot PR'ni to'xtatdi: "commits are not signed off". Davosi: git commit --amend -s --no-edit yoki bir nechta commit uchun git rebase --signoff, keyin force-with-lease bilan push.

9. Mashqlar

Mashqlar kurs/mashqlar/32/19-open-source/ da. 2-mashq yechimi Node 24.21.0 da, 3-mashq yechimi Git 2.54.0 da tekshirilgan (biz ishga tushirdik).

1-mashq (oson): bo'shliqlarni to'ldiring

  • Yangi kelganlar uchun issue'larni belgilaydigan GitHub label'i —
  • Commit oxiriga Signed-off-by: qatorini qo'shadigan bayroq — git commit
  • Tarmoq orqali xizmat ko'rsatishni ham tarqatish deb hisoblaydigan litsenziya —
  • FSF GPLv2 bilan mos deb hisoblamagan ruxsat beruvchi litsenziya —
  • Hissa loyiha litsenziyasi ostida qabul qilinadi degan qoida — inbound =
Yechim
  • good first issue — GitHub bunday issue'larni yangi kelganlarga ko'rsatadi.
  • -s — DCO; katta -S — kriptografik imzo, boshqa narsa.
  • AGPL-3.0 — GPL'ning SaaS "teshigi"ni yopadi.
  • Apache-2.0 — patent bandi tufayli; GPLv3 bilan esa mos.
  • outbound — CLA'siz loyihalarda odatiy kelishuv.

2-mashq (o'rta): litsenziya muvofiqligi

moslik(loyiha, bogliqlik) funksiyasini yozing. U "loyiha litsenziyali dasturga bogliqlik litsenziyali kodni qo'shib tarqatsa bo'ladimi?" savoliga satr bilan javob bersin. Soddalashtirilgan qoidalar:

  • bir xil litsenziya yoki ruxsat beruvchi (MIT, ISC, BSD-2-Clause, BSD-3-Clause, 0BSD) — "ha";
  • Apache-2.0 — "ha", faqat GPL-2.0-only loyihaga "yo'q: GPLv2 bilan zid";
  • MPL-2.0 — "ha, MPL fayllari ochiq qoladi";
  • kopileft (GPL-2.0-only, GPL-3.0-only, AGPL-3.0-only) kopileft bo'lmagan loyihaga — "yo'q: butun ish <bogliqlik> bo'ladi"; GPL-3.0-only ga AGPL-3.0-only — "ha, birlashma AGPL shartida"; boshqa kopileft juftlari — "yo'q: versiyalar mos emas";
  • ro'yxatda yo'q — "noma'lum: qo'lda tekshiring".

Ishora: shartlar tartibi muhim — avval eng sodda holatlar. Massivda borligini includes tekshiradi (Matn ichida qidirish darsidagi satr metodi massivda ham bor). Bu jadval — o'quv modeli, yuridik xulosa emas.

Yechim
js
const RUXSATLI = [
  "MIT", "ISC", "BSD-2-Clause", "BSD-3-Clause", "0BSD",
];
const KOPILEFT = ["GPL-2.0-only", "GPL-3.0-only", "AGPL-3.0-only"];

function moslik(loyiha, bogliqlik) {
  if (bogliqlik === loyiha) return "ha";
  if (RUXSATLI.includes(bogliqlik)) return "ha";
  if (bogliqlik === "Apache-2.0") {
    return loyiha === "GPL-2.0-only" ? "yo'q: GPLv2 bilan zid" : "ha";
  }
  if (bogliqlik === "MPL-2.0") return "ha, MPL fayllari ochiq qoladi";
  if (KOPILEFT.includes(bogliqlik)) {
    if (!KOPILEFT.includes(loyiha)) {
      return `yo'q: butun ish ${bogliqlik} bo'ladi`;
    }
    if (loyiha === "GPL-3.0-only" && bogliqlik === "AGPL-3.0-only") {
      return "ha, birlashma AGPL shartida";
    }
    return "yo'q: versiyalar mos emas";
  }
  return "noma'lum: qo'lda tekshiring";
}

const savollar = [
  ["MIT", "ISC"],
  ["MIT", "MPL-2.0"],
  ["MIT", "GPL-3.0-only"],
  ["GPL-3.0-only", "Apache-2.0"],
  ["GPL-2.0-only", "Apache-2.0"],
  ["GPL-3.0-only", "AGPL-3.0-only"],
  ["GPL-2.0-only", "GPL-3.0-only"],
  ["MIT", "BlueOak-1.0.0"],
];
for (const [loyiha, b] of savollar) {
  console.log(`${loyiha} ← ${b}: ${moslik(loyiha, b)}`);
}

Konsolda:

text
MIT ← ISC: ha
MIT ← MPL-2.0: ha, MPL fayllari ochiq qoladi
MIT ← GPL-3.0-only: yo'q: butun ish GPL-3.0-only bo'ladi
GPL-3.0-only ← Apache-2.0: ha
GPL-2.0-only ← Apache-2.0: yo'q: GPLv2 bilan zid
GPL-3.0-only ← AGPL-3.0-only: ha, birlashma AGPL shartida
GPL-2.0-only ← GPL-3.0-only: yo'q: versiyalar mos emas
MIT ← BlueOak-1.0.0: noma'lum: qo'lda tekshiring

To'rtinchi va beshinchi qatorlar — bir xil bog'liqlik, har xil javob: GPL versiyasi hal qiladi. Oltinchisida GPLv3 ning 13-bandi («Use with the GNU Affero General Public License») ishlaydi: u AGPL bilan birlashtirishga ruxsat beradi. GPL qismi GPL'da qoladi, lekin AGPL'ning tarmoq sharti butun birlashmaga tegishli bo'ladi (gnu.org, 2026-11-04). Uchinchi qatordagi "yo'q" — "qonun bilan taqiqlangan" degani emas. Birlashmani faqat GPL ostida tarqata olasiz, MIT loyihaning va'dasi esa buziladi. Oxirgi qator eng foydali: BlueOak-1.0.0 — ruxsat beruvchi litsenziya va kurs loyihasida u bor (minimatch). Lekin bizning jadvalda yo'q. Avtomatik tekshiruvlar aynan shunday ishlaydi: bilmaganini "noma'lum" deb odamga beradi — va bu to'g'ri xulq.

3-mashq (qiyin): birinchi hissa — lokal o'xshatish

kurs/mashqlar/32/19-open-source/hissa-yarat.sh ikki bare repo yaratadi: loyiha.git — Jasur akaning asl loyihasi (upstream), fork.git — uning nusxasi, GitHub'dagi fork o'rnida. Fork olingandan keyin asl loyihaga yana bitta commit tushgan. README'da imlo xatosi bor: "tushrish". Muallif va sanalar qotirilgan — SHA'lar sizda ham bir xil chiqadi.

  1. bash hissa-yarat.sh hissa va cd hissa.
  2. Fork'ni men papkaga klon qiling, upstream qo'shing va fork necha commit orqadaligini chiqaring.
  3. upstream/main dan docs/readme-imlo branch oching (fork'ning eski main idan emas!).
  4. Imloni tuzating va DCO bilan commit qiling.
  5. Branch'ni origin ga (fork'ga) yuboring.
  6. Ko'rsating: remote'lar, upstream/main dan keyingi commitlar, commit trailer'i va branch qaysi remote'da borligi.

Ishora: Fork va upstream darsidagi git remote add upstream; orqada qolish — git rev-list --count main..upstream/main. Faylda so'zni almashtirish — sed -i 's/eski/yangi/' fayl. SHA darsdagidek chiqishi uchun muallif va sanani qotiring: GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL ga Aziz Karimov / aziz@example.com, ikkala sanaga 2026-11-04T10:00:00+05:00.

Yechim
bash
bash hissa-yarat.sh hissa && cd hissa
export GIT_AUTHOR_NAME="Aziz Karimov"
export GIT_AUTHOR_EMAIL="aziz@example.com"
export GIT_COMMITTER_NAME="Aziz Karimov"
export GIT_COMMITTER_EMAIL="aziz@example.com"
export GIT_AUTHOR_DATE="2026-11-04T10:00:00+05:00"
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"

git clone -q fork.git men && cd men
git remote add upstream ../loyiha.git
git fetch -q upstream
echo "fork orqada: $(git rev-list --count main..upstream/main) commit"
git switch -q -c docs/readme-imlo upstream/main
sed -i 's/tushrish/tushirish/' README.md
git commit -q -a -s -m "docs: README imlosi"
git push -q -u origin docs/readme-imlo 2>&1
git remote
git log --format='%h %an: %s' upstream/main..
git log -1 --format='%(trailers)'
git branch -r --contains HEAD

Biz ishga tushirdik:

text
fork orqada: 1 commit
origin
upstream
03385d2 Aziz Karimov: docs: README imlosi
Signed-off-by: Aziz Karimov <aziz@example.com>

  origin/docs/readme-imlo

Qatorma-qator. Fork bitta commit orqada — Jasur aka fork'dan keyin oylar.js ni qo'shgan. Branch upstream/main dan ochilgani uchun bu farq muammo emas: PR'ingiz eng yangi kod ustida. Fork'ning eski main idan ochganingizda, PR'da "eski asos" bo'lardi va maintainer rebase so'rardi. upstream/main.. — "upstream'da yo'q, menda bor" commitlar: faqat bittasi, sizniki. Toza, bitta ishli PR. Trailer — DCO qatori, CONTRIBUTING.md talabi bajarildi. Oxirgi qator: branch faqat origin da, ya'ni fork'da. Asl loyihaga hech narsa yozilmagan — u yerga o'zgarish faqat PR merge bo'lganda tushadi. GitHub'da keyingi qadam — fork sahifasidagi "Compare & pull request" tugmasi yoki gh pr create --repo jasur/sana-uz.

10. Real ishda

  • Qayerda uchraydi: kompaniyalarning ko'pi o'z kodida open source kutubxonalar ishlatadi va yangi paket qo'shishdan oldin litsenziyani tekshiradi. Ba'zi kompaniyalarda buning uchun "open source dasturlar idorasi" (OSPO) bor.
  • Karyera: haqiqiy loyihadagi merge bo'lgan PR — intervyuda aytib berish mumkin bo'lgan hikoya: muammo, muloqot, review, natija. GitHub profilingizdagi tashqi hissalar buni ko'rsatadi.
  • Maintainer bo'lish: o'z kutubxonangizda siz good first issue yozasiz va PR'larni review qilasiz — qismdagi hamma ko'nikma bir joyda.
  • Intervyu savollari: "Open source'ga hissa qo'shganmisiz? Qanday?", "MIT va GPL farqi nima?", "AGPL'li kutubxonani SaaS'da ishlatsa bo'ladimi?", "Loyihaga yangi bog'liqlik qo'shishdan oldin nimani tekshirasiz?"

Xulosa

  • Open source = ochiq kod + ruxsat beruvchi litsenziya; litsenziyasiz public repo ochiq emas.
  • Hissa oqimi: good first issue → CONTRIBUTING → issue'da xabar → kichik PR → sabrli review.
  • DCO (git commit -s) — "huquqim bor" degan qator; CLA — alohida shartnoma.
  • MIT va Apache-2.0 — ruxsat beruvchi; GPL — hosila ish ham ochiq; AGPL — tarmoq xizmati ham.
  • Muvofiqlik bir yo'nalishli: ruxsat beruvchi kod kopileft'ga kiradi, teskarisi — yo'q.
  • Kanon: 876 paketda GPL/AGPL yo'q; MIT LICENSE PR #19 bilan qo'shildi.

32-qism yakuni

Bu dars bilan 32-qism tugadi. vazifalar-api endi faqat ishlaydigan kod emas — u jamoa ishlay oladigan repo. Kurs sinov reposidagi main tarixi buni ko'rsatadi. Birinchi commit — 31-qism yakunidagi loyihani repoga olib kirish. Undan keyingi har commit — bitta PR, hammasi squash bilan. #10 va #16 yo'q: ular issue, chunki GitHub issue va PR'ga bitta raqamlar qatorini beradi.

gitGraph
  commit id: "v4.0.0 import"
  commit id: "#9 breaker"
  commit id: "#11 4.0.1" tag: "v4.0.1"
  commit id: "#12 CODEOWNERS"
  commit id: "#13 ARXITEKTURA"
  commit id: "#14 CONTRIBUTING"
  commit id: "#15 README"
  commit id: "#17 shablon, ADR"
  commit id: "#18 talablar"
  commit id: "#19 LICENSE"
  commit id: "#20 sayt"

Grafdagi v4.0.1 — o'quvchi repo'sidagi tag nomi. Kanondagi tag nomi monorepo sababli boshqacha.

Qism bo'yicha qisqa yakun:

Mavzu Natija
Git chuqur bisect (93a6b16 3 qadamda) va 31-qism nuqsonlari, reliz 4.0.1, GitHub flow, imzo, tarix tozalash
Katta repo va sozlama shallow va partial clone, sparse-checkout, LFS, monorepo, CODEOWNERS, path filtr, alias va rerere
Yangi loyihaga kirish docs/ARXITEKTURA.md, birinchi vazifa (#8)
PR va review PR shabloni, CONTRIBUTING, Conventional Comments

Davomi:

Mavzu Natija
Hujjat va muloqot README, SECURITY, issue shablonlari, ADR, inglizcha commit va PR
Jarayon Scrum, Kanban label'lari, epic va 16 SP, talab hujjati
Open source MIT LICENSE, litsenziyalar, hissa oqimi, PR #20

Bir narsani halol aytamiz: kanonda ochiq qolganlar ham bor. "Verified" belgisi, required status checks, merge queue, GitHub Projects va fork sinalmagan. auth.test dagi beqaror test hali barqarorlashtirilmagan. CI'da MinIO va Mailpit yo'q. Bularning bir qismi keyingi qismlarda yopiladi.

33-qismga ko'prik. Hozirgacha vazifalar-api faqat sizning kompyuteringizda va CI faylida yashadi. GitHub Actions fayli bor, lekin u hali haqiqiy serverga hech narsa chiqarmagan. Keyingi qismda dastur kompyuteringizdan chiqadi: Linux server, foydalanuvchilar va ruxsatlar, systemd, loglar, SSH, domen va HTTPS, Nginx va Docker — ilovani hamma joyda bir xil ishlaydigan "quti"ga joylash. Qism oxirida vazifalar-api ni o'z serveringizga qo'lda deploy qilasiz. 31-qismda "kanon shunday ishga tushirdi" deb ko'rgan Docker buyruqlari endi sizning qo'lingizda bo'ladi.

Keyingi dars: Server nima va ilova qayerda ishlaydi — VPS, dedicated server, bulut va PaaS: vazifalar-api uchun uy tanlaymiz.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Open source: hissa qo'shish va litsenziyalar — MIT, Apache-2.0, GPL, AGPL — IlmHamroh