Chapterبەش 3 · Lectureوانە 3.1
Versions and Builds: What 1.0.0 Meansوەشانەکان و بیلدەکان: 1.0.0 واتای چییە
What version numbers promise and how software is built and released: version vs build vs release, Semantic Versioning 2.0.0 (MAJOR.MINOR.PATCH, breaking changes, resets), what 1.0.0 means, pre-releases and build metadata, a runnable semver sort in Python and the text-sorting mistake, CalVer, PEP 440, Java LTS, Android versionCode and Flutter's version line, version constraints and lock files, build pipelines and artifacts (a zipapp .pyz), debug vs release builds, annotated Git tags and git describe, changelogs, and continuous delivery vs deployment — told through Bazaar Cart's version story from 0.1.0 to 2.0.0.
ژمارەی چ بەڵێنێک دەدات و چۆن و بڵاو دەکرێتەوە: ، و ، 2.0.0 (MAJOR.MINOR.PATCH، ، سفرکردنەوە)، 1.0.0 واتای چییە، و زانیاریی ، ڕیزکردنی semver بە Python و هەڵەی ڕیزکردن وەک دەق، CalVer، PEP 440، LTSـی Java، versionCodeـی Android و دێڕی وەشانی Flutter، و ، زنجیرەی و (.pyzـێکی zipapp)، debug و release، ڕوونکراوە و git describe، و بەرامبەر — لە ڕێگەی چیرۆکی Bazaar Cart لە 0.1.0ـەوە تا 2.0.0.
What you will learnچی فێر دەبیت
- Tell a version, a build and a release apart.
- Choose the next semantic version for a change, and explain what 0.y.z and 1.0.0 promise.
- Order versions with pre-releases and build metadata, in your head and in Python, and avoid sorting them as text.
- Read other schemes (CalVer, PEP 440, Android and Flutter version numbers) and dependency constraints with lock files.
- Build a runnable artifact, tag a release in Git, write a changelog entry, and tell continuous delivery from continuous deployment.
- ، و لە یەک جیا بکەیتەوە.
- داهاتووی بۆ گۆڕانکارییەک هەڵبژێریت و ڕوون بکەیتەوە 0.y.z و 1.0.0 چ بەڵێنێک دەدەن.
- لەگەڵ و زانیاریی ڕیز بکەیت، لە مێشکتدا و بە Python و خۆت لە ڕیزکردنیان وەک دەق بپارێزیت.
- شێوازەکانی تر بخوێنیتەوە (CalVer، PEP 440، ژمارەی وەشانی Android و Flutter) و لەگەڵ .
- کارپێکراو بکەیت، لە Gitـدا تاگ بکەیت، بەشێکی بنووسیت و لە جیا بکەیتەوە.
1.0.0, 1.0.1, 2.0.0: what do the numbers promise?1.0.0، 1.0.1، 2.0.0: ژمارەکان چ بەڵێنێک دەدەن؟
Bazaar Cart has a history in numbers. The team released 0.1.0, 0.2.0 and 0.3.0 while they were still building, and 1.0.0 when Soran's shop began taking real orders. A rounding bug led to 1.0.1, a discount to 1.1.0, and a change that broke other programs to 2.0.0. Each number tells users something before they update.
Bazaar Cart مێژوویەکی هەیە بە ژمارە. تیمەکە 0.1.0، 0.2.0 و 0.3.0ـی بڵاو کردەوە کاتێک هێشتا دروستیان دەکرد و 1.0.0 کاتێک دوکانەکەی سۆران دەستی کرد بە وەرگرتنی داواکاریی ڕاستەقینە. بەرزکردنەوەی نرخ بوو بە هۆی 1.0.1، داشکانێک بوو بە هۆی 1.1.0 و گۆڕانکارییەک کە تری تێکدا بوو بە هۆی 2.0.0. هەر ژمارەیەک پێش شتێک بە دەڵێت.
Other programs use Bazaar Cart's code: the shop's website and its Telegram bot call line_price(), delivery_fee() and place_order(). These functions, with their parameters and results, are Bazaar Cart's public API — and the public API is what the numbers make promises about.
تر کۆدی Bazaar Cart بەکار دەهێنن: ماڵپەڕی دوکانەکە و بۆتی تێلێگرامەکەی بانگی line_price()، delivery_fee() و place_order() دەکەن. ئەم لەگەڵ و ئەنجامەکانیان گشتیی Bazaar Cartـن — و ژمارەکان لەبارەی گشتی بەڵێن دەدەن.


Version, build and releaseوەشان، بیلد و وەشانی بڵاوکراوە
Three words that are easy to mix up (the words in English):
سێ وشە کە بە ئاسانی تێکەڵ دەکرێن (وشەکان بە ئینگلیزی):
- Version: one numbered state of the software, such as 1.0.1.
- Build: turning source code into something that runs, and the result of one such run. A team may build many times a day; each build gets a build number.
- Release: a version given to people outside the team — customers, an app store, other programs.
- : یەک دۆخی ژمارەداری ، وەک 1.0.1.
- : گۆڕینی بۆ شتێک کە کار دەکات و ئەنجامی یەک جار لەو کارە. تیمێک لەوانەیە ڕۆژانە چەندین جار بکات؛ هەر ژمارەیەک وەردەگرێت، کە پێی دەوترێت .
- : کە دەدرێت بە خەڵکی دەرەوەی تیمەکە — کڕیاران، ، تر.
The baker's recipe is the version (“recipe 3”). Every batch he bakes from it is a build (batch 57, batch 58…). The batch he puts on the counter for customers is the release. He may bake test batches that nobody buys.
ڕەچەتەی نانەواکە («ڕەچەتەی 3»). هەر جارێک کە لێیەوە نان دەکات (جاری 57، جاری 58…). ئەو نانەی دایدەنێت لەسەر پێشخانەکە بۆ کڕیاران . لەوانەیە نانی تاقیکردنەوەش بکات کە کەس نایکڕێت.
Where the analogy stops workingسنووری ئەم نموونەیە
Two batches of bread are never exactly the same; two builds of the same code should be.
دوو جاری نان هەرگیز ڕێک وەک یەک نین؛ دوو هەمان کۆد دەبێت وەک یەک بن.
Semantic Versioning: MAJOR.MINOR.PATCHوەشانبەندیی واتایی: MAJOR.MINOR.PATCH
Most libraries and many apps follow Semantic Versioning 2.0.0 (semver.org), written by Tom Preston-Werner, a co-founder of GitHub. A version has three numbers, MAJOR.MINOR.PATCH, and each one tells the users of your public API what kind of change happened:
زۆربەی و زۆر پەیڕەوی 2.0.0 (semver.org) دەکەن، کە تۆم پرێستن-وێرنەر، یەکێک لە دامەزرێنەرانی GitHub، نووسیویەتی. سێ ژمارەی هەیە (MAJOR.MINOR.PATCH) و هەر یەکەیان بە بەکارهێنەرانی گشتیت دەڵێت چ جۆرە گۆڕانکارییەک ڕووی داوە:
- PATCH goes up for bug fixes that break nothing: 1.0.0 → 1.0.1.
- MINOR goes up for new features that break nothing, and when something is marked deprecated; PATCH goes back to 0: 1.0.1 → 1.1.0.
- MAJOR goes up for a breaking change: code that worked with the old version may stop working. MINOR and PATCH go back to 0: 1.1.0 → 2.0.0.
- PATCH () بۆ چاککردنەوەی زیاد دەبێت کە هیچ شتێک تێک نادات: 1.0.0 → 1.0.1.
- MINOR () بۆ تایبەتمەندیی نوێ کە هیچ شتێک تێک نادات زیاد دەبێت، هەروەها کاتێک شتێک وەک نیشان دەکرێت؛ PATCH دەگەڕێتەوە بۆ 0: 1.0.1 → 1.1.0.
- MAJOR () بۆ زیاد دەبێت: کۆدێک کە لەگەڵ کۆن کاری دەکرد لەوانەیە ئیتر کار نەکات. MINOR و PATCH دەگەڕێنەوە بۆ 0: 1.1.0 → 2.0.0.
One more rule: once a version is released, its contents never change. Every change, however small, needs a new number.
یاسایەکی تر: کاتێک بڵاو کرایەوە، ناوەڕۆکەکەی هەرگیز ناگۆڕێت. هەموو گۆڕانکارییەک، هەرچەند بچووک بێت، ژمارەیەکی نوێی پێویستە.
Semantic Versioning: MAJOR.MINOR.PATCHوەشانبەندیی واتایی: MAJOR.MINOR.PATCH
Which number goes up?کام ژمارە زیاد دەبێت؟
Ask three questions in this order; the first yes decides. The number that goes up resets every number to its right to 0. Version numbers are not decimals: after 1.9.0 comes 1.10.0, not 2.0.
سێ پرسیار بەم ڕیزە بکە؛ یەکەم بەڵێ بڕیار دەدات. ئەو ژمارەیەی زیاد دەبێت هەموو ژمارەکانی لای ڕاستی دەگەڕێنێتەوە بۆ 0. ژمارەی ژمارەی دەیی نییە: دوای 1.9.0 دێت 1.10.0، نەک 2.0.
What 1.0.0 means1.0.0 واتای چییە
Major version zero (0.y.z) is for early development: anything may change at any time, and nobody should treat the API as stable. Semver's FAQ suggests starting at 0.1.0 and raising MINOR with every release — exactly what Bazaar Cart did.
سفر (0.y.z) بۆ قۆناغی سەرەتای گەشەپێدانە: هەر شتێک هەر کاتێک لەوانەیە بگۆڕێت و کەس نابێت وەک شتێکی جێگیر سەیر بکات. پرسیارە باوەکانی semver پێشنیار دەکەن لە 0.1.0ـەوە دەست پێ بکەیت و لەگەڵ هەر MINOR زیاد بکەیت — ڕێک ئەوەی Bazaar Cart کردی.
1.0.0 defines the public API. From then on, the numbers keep their promise: no breaking change without a new MAJOR. Release 1.0.0 when people use the software in production or depend on its API. The FAQ puts it simply: if you already worry a lot about backward compatibility, you should probably be at 1.0.0 already.
1.0.0 گشتی دیاری دەکات. لەوە بەدواوە ژمارەکان بەڵێنەکەیان دەپارێزن: هیچ بەبێ MAJORـی نوێ نییە. 1.0.0 بڵاو بکەرەوە کاتێک خەڵک بە ڕاستی بەکار دەهێنن یان پشت بە دەبەستن. پرسیارە باوەکان بە سادەیی دەیڵێن: ئەگەر ئێستا زۆر نیگەرانی لەگەڵ کۆنیت، لەوانەیە دەبوو پێشتر گەیشتبیتە 1.0.0.
1.0.0 does not mean perfect, finished or bug-free. That is why 1.0.1 exists.
1.0.0 واتای تەواو، کۆتاییهاتوو یان بێ نییە. بۆیە 1.0.1 هەیە.
Pre-releases and build metadataوەشانەکانی پێش بڵاوکردنەوە و زانیاریی بیلد
Before a big release, teams publish test versions. A pre-release adds a hyphen and labels after PATCH: 1.0.0-alpha, 1.0.0-beta.2, 1.0.0-rc.1. Alpha is early and incomplete. A beta version is nearly finished and given to some real users to find bugs. rc means release candidate: it becomes the release if no serious bug appears. Real labels in 2026: ArtCraft's apps are marked early alpha and numbered 0.x (Case Study: ArtCraft).
پێش گەورە، تیمەکان تاقیکردنەوە بڵاو دەکەنەوە. خەتێکی بچووک و نیشانە دوای PATCH زیاد دەکات: 1.0.0-alpha، 1.0.0-beta.2، 1.0.0-rc.1. ئەلفا سەرەتایی و ناتەواوە. نزیکە لە تەواوبوون و دەدرێت بە هەندێک ڕاستەقینە بۆ دۆزینەوەی . rc واتە کاندیدی بڵاوکردنەوە: ئەگەر هیچ گەورە دەرنەکەوت، دەبێت بە . نیشانەی ڕاستەقینە لە 2026دا: ArtCraft وەک سەرەتایی نیشان کراون و ژمارەکانیان بە 0 دەست پێ دەکەن (نموونەیەکی ڕاستەقینە: ArtCraft).
To decide which version is newer, semver compares MAJOR, MINOR and PATCH as numbers, then ranks every pre-release below its normal version. Labels are compared part by part: numbers as numbers, words in ASCII order, and a longer list wins when the first parts are equal. Build metadata after a plus (1.0.0+57) is ignored.
بۆ ئەوەی دیاری بکرێت کام نوێترە، semver MAJOR، MINOR و PATCH وەک ژمارە بەراورد دەکات، دواتر هەموو لە خوار دادەنێت. نیشانەکان بەش بە بەش بەراورد دەکرێن: ژمارە وەک ژمارە، وشە بە ڕیزی ASCII و لیستی درێژتر دەباتەوە ئەگەر بەشەکانی سەرەتا وەک یەک بن. زانیاریی دوای + (1.0.0+57) پشتگوێ دەخرێت.
Comparing versions in Pythonبەراوردکردنی وەشانەکان لە Pythonـدا
A short program can sort versions the semver way. A regular expression splits a version into its parts, and semver_key() turns each version into a tuple, which Python compares part by part.
کورت دەتوانێت بە شێوەی semver ڕیز بکات. بۆ بەشەکانی دابەش دەکات و semver_key() هەر دەکات بە ، کە Python بەش بە بەش بەراوردی دەکات.
"""Compare version numbers the Semantic Versioning 2.0.0 way."""
import re
PATTERN = re.compile(
r"(\d+)\.(\d+)\.(\d+)" # MAJOR.MINOR.PATCH
r"(?:-([0-9A-Za-z.-]+))?" # -pre-release (optional)
r"(?:\+([0-9A-Za-z.-]+))?" # +build metadata (optional, ignored)
)
def semver_key(version):
"""A sort key: numbers compare as numbers, pre-releases come first."""
m = PATTERN.fullmatch(version)
if m is None:
raise ValueError(f"not a semantic version: {version!r}")
major, minor, patch = int(m[1]), int(m[2]), int(m[3])
if m[4] is None: # a normal release ...
pre = (1,) # ... ranks above its pre-releases
else:
parts = []
for part in m[4].split("."): # alpha.1 -> "alpha", "1"
if part.isdigit():
parts.append((0, int(part), "")) # numbers first, by value
else:
parts.append((1, 0, part)) # then words, A-Z order
pre = (0, parts)
return (major, minor, patch, pre)
if __name__ == "__main__":
versions = ["1.10.0", "1.0.0", "2.0.0", "1.0.0-rc.1", "1.9.0",
"1.0.0-beta.11", "1.0.0-alpha", "1.0.0-beta.2", "0.3.0"]
print(sorted(versions, key=semver_key))
print(semver_key("1.0.0+57") == semver_key("1.0.0"))['0.3.0', '1.0.0-alpha', '1.0.0-beta.2', '1.0.0-beta.11', '1.0.0-rc.1', '1.0.0', '1.9.0', '1.10.0', '2.0.0'] True
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 4-8
Three numbers, then an optional
-pre-releaseand an optional+buildpart.سێ ژمارە، دواتر بەشێکی ئارەزوومەندانەی
-pre-releaseو بەشێکی ئارەزوومەندانەی+build.- Lineدێڕی 16
int()makes 10 bigger than 9 — the whole point.int()10 لە 9 گەورەتر دەکات — ئەمە هەموو مەبەستەکەیە.- Lineدێڕی 17-18
A normal release gets
(1,); a pre-release gets(0, …), so it sorts lower.ئاسایی
(1,)وەردەگرێت؛(0, …)وەردەگرێت، بۆیە لە خوارەوە ڕیز دەکرێت.- Lineدێڕی 22-25
Numeric labels rank below words; numbers compare by value, words in ASCII order.
نیشانە ژمارەییەکان لە خوار وشەکانەوەن؛ ژمارە بە بەها و وشە بە ڕیزی ASCII بەراورد دەکرێن.
- Lineدێڕی 34
Build metadata is ignored: 1.0.0+57 and 1.0.0 get the same key.
زانیاریی پشتگوێ دەخرێت: 1.0.0+57 و 1.0.0 هەمان کلیل وەردەگرن.
Package managers such as pip, pub and npm do this comparison for you every time they choose a version. Writing it once shows why versions must never be compared as plain text — the next screen.
وەک pip، pub و npm هەموو جارێک کە هەڵدەبژێرن ئەم بەراوردە بۆت دەکەن. نووسینی بۆ یەک جار پیشان دەدات بۆچی هەرگیز نابێت وەک دەقی ئاسایی بەراورد بکرێن — شاشەی داهاتوو.
Comparing versions in Pythonبەراوردکردنی وەشانەکان لە Pythonـدا
A common mistake: sorting versions as textهەڵەیەکی باو: ڕیزکردنی وەشانەکان وەک دەق
Versions look like text, but text is compared character by character (lexicographic order). At the third character 1 (from 1.10.0) is smaller than 9, so “1.10.0” comes first. The fix is to compare numbers:
وەک دەق دەردەکەون، بەڵام دەق پیت بە پیت بەراورد دەکرێت (ڕیزبەندیی فەرهەنگی). لە پیتی سێیەمدا 1 (لە 1.10.0) لە 9 بچووکترە، بۆیە «1.10.0» یەکەم دێت. چارەسەرەکە بەراوردکردنی ژمارەکانە:
versions = ["1.9.0", "1.10.0", "1.2.0"]
print(sorted(versions)) # strings: compared letter by letter
print("1.10.0" > "1.9.0")
def numbers(version):
return tuple(int(n) for n in version.split("."))
print(sorted(versions, key=numbers)) # (1, 10, 0) > (1, 9, 0)
print(numbers("1.10.0") > numbers("1.9.0"))['1.10.0', '1.2.0', '1.9.0'] False ['1.2.0', '1.9.0', '1.10.0'] True
Git has the same trap: git tag lists tags in alphabetical order, while git tag --sort=v:refname sorts them as versions:
Git هەمان تەڵەی هەیە: git tag بە ڕیزی ئەلفوبێ لیست دەکات، بەڵام git tag --sort=v:refname وەک ڕیزیان دەکات:
git tag
git tag --sort=v:refname$ git tag v1.10.0 v1.2.0 v1.9.0 $ git tag --sort=v:refname v1.2.0 v1.9.0 v1.10.0
Other numbering schemesشێوازەکانی تری ژمارەدانان
Semver is not the only scheme. You will meet these too:
semver تاکە شێواز نییە. ئەمانەش دەبینیت:
- Calendar versioning (CalVer): the number is a date. Ubuntu 26.04 LTS came out in April 2026 (year.month); pip uses year.minor.micro. It tells when a version came out, not how much changed — useful for software released on a timetable.
- Python packages (PEP 440): pre-releases are written
1.0.0a1,1.0.0b2,1.0.0rc1, plus1.0.0.post1and1.0.0.dev0; Python itself came as 3.13.0rc1 before 3.13.0. MAJOR.MINOR.PATCH fits, but semver's hyphen and plus parts are not allowed in published versions:1.0.0-rc.1becomes1.0.0rc1. - Java: a feature release every six months and a long-term support version every two years;
17.0.20means Java 17, update 20 (Java versions).
- (CalVer): ژمارەکە ڕێکەوتێکە. Ubuntu 26.04 LTS لە نیسانی 2026ـدا دەرچوو (ساڵ.مانگ)؛ pip ساڵ.minor.micro بەکار دەهێنێت. دەڵێت کەی دەرچوو، نەک چەند گۆڕاوە — بۆ کە بە خشتەی کات دەردەچێت بەسوودە.
- Python (PEP 440): بەم شێوەیە دەنووسرێن
1.0.0a1،1.0.0b2،1.0.0rc1، لەگەڵ1.0.0.post1و1.0.0.dev0؛ خودی Python وەک 3.13.0rc1 پێش 3.13.0 هات. MAJOR.MINOR.PATCH دەگونجێت، بەڵام بەشی خەت و +ـی semver لە بڵاوکراوەدا ڕێگەپێدراو نین:1.0.0-rc.1دەبێت بە1.0.0rc1. - Java: هەر شەش مانگ و هەر دوو ساڵ ؛
17.0.20واتە Java 17، 20 (وەشانەکانی Java).
Other numbering schemesشێوازەکانی تری ژمارەدانان
Version numbers in mobile appsژمارەی وەشان لە ئەپەکانی مۆبایلدا
An Android app carries two numbers. versionName is the text users see, such as "1.0.1". versionCode is a whole number users never see. It must grow with every upload: Android will not install a lower versionCode over a higher one, Google Play rejects a versionCode you have already used, and the largest allowed value is 2,100,000,000.
Android دوو ژمارە هەڵدەگرێت. versionName ئەو دەقەیە کە دەیبینن، وەک "1.0.1". versionCode کە هەرگیز نایبینن. دەبێت لەگەڵ هەر زیاد بێت: Android versionCodeـێکی نزمتر لە سەر بەرزترێک دانامەزرێنێت، Google Play versionCodeـێک کە پێشتر بەکارت هێناوە ڕەت دەکاتەوە و گەورەترین بەهای ڕێگەپێدراو 2,100,000,000ـە.
Flutter writes both in one line of pubspec.yaml (the project file): version: 1.0.1+2. The part before + becomes versionName; the number after it is the build number and becomes versionCode. You can also set them when building: flutter build appbundle --build-name=1.0.1 --build-number=2.
Flutter هەردووکیان لە یەک دێڕی pubspec.yamlـدا دەنووسێت (فایلی پڕۆژەکە): version: 1.0.1+2. بەشی پێش + دەبێت بە versionName؛ ژمارەکەی دوای ئەوە ـە و دەبێت بە versionCode. دەتوانیت لە کاتی دیاریشیان بکەیت: flutter build appbundle --build-name=1.0.1 --build-number=2.
Why package managers care about semverبۆچی بەڕێوەبەرەکانی پاکێج گرنگی بە semver دەدەن
Your project depends on other people's packages, and they release new versions too. A version constraint says which versions you accept. Because of semver, a constraint can safely say “newer versions with the same MAJOR are fine”:
پڕۆژەکەت پشت بە خەڵکی تر دەبەستێت و ئەوانیش نوێ بڵاو دەکەنەوە. دەڵێت کام وەردەگریت. بەهۆی semverـەوە دەتوانێت بە دڵنیاییەوە بڵێت « نوێتر بە هەمان MAJOR باشن»:
^1.2.3(Dart's pub, npm): at least 1.2.3 and below 2.0.0. Below 1.0 the caret stops earlier:^0.20.3stops before 0.21.0. The full table is in Dependencies and version constraints.~=1.4.5(Python's pip, PEP 440): at least 1.4.5 and still 1.4..~=2.2means at least 2.2 and still 2..
^1.2.3(pubـی Dart، npm): لانیکەم 1.2.3 و لە خوار 2.0.0. لە خوار 1.0ـەوە نیشانەی^زووتر دەوەستێت:^0.20.3پێش 0.21.0 دەوەستێت. خشتە تەواوەکە لە وابەستەییەکان و مەرجەکانی وەشانـدایە.~=1.4.5(pipـی Python، PEP 440): لانیکەم 1.4.5 و هێشتا 1.4..~=2.2واتە لانیکەم 2.2 و هێشتا 2..
Ranges let fixes in, but two computers could still choose different versions on different days. A lock file (pubspec.lock, package-lock.json) records the exact version of every dependency that was installed, so every computer — and the build server — builds with the same ones. Dart's guide: commit the lock file of an app, not of a library.
مەوداکان ڕێگە بە چاککردنەوەکان دەدەن، بەڵام دوو کۆمپیوتەر هێشتا دەتوانن لە دوو ڕۆژی جیاوازدا جیاواز هەڵبژێرن. (pubspec.lock، package-lock.json) ڕێک هەموو ئەو دامەزراون تۆمار دەکات، بۆ ئەوەی هەموو کۆمپیوتەرێک — و — بە هەمان بکات. ڕێبەری Dart دەڵێت: بکە، نەک هی .
Builds: from source code to an artifactبیلد: لە کۆدی سەرچاوەوە بۆ بەرهەمی بیلد
A build puts the right versions of all the parts together into something that can run or be installed. A typical build runs the same steps every time: get the source code of one commit, check it (compile it, look for obvious errors), run the tests, and package it.
دروستی هەموو بەشەکان پێکەوە دەنێت بۆ شتێک کە کار بکات یان دابمەزرێت. ئاسایی هەموو جارێک هەمان هەنگاوەکان دەکات: یەک وەردەگرێت، دەیپشکنێت ( بەکار دەهێنێت، بەدوای هەڵەی ئاشکرادا دەگەڕێت)، تاقیکردنەوەکان جێبەجێ دەکات و دەیپێچێتەوە.
The result is a build artifact: the file you test, keep and give to users — an Android app bundle (.aab), a Windows .exe, a Java .jar, a Python .pyz. Each build gets a build number that only goes up, so everyone can say exactly which build they tested.
ئەنجامەکە ـە: ئەو تاقیی دەکەیتەوە، هەڵیدەگریت و دەیدەیت بە — app bundleـی Android (.aab)، .exeـی Windows، .jarـی Java، .pyzـی Python. هەر ژمارەیەک وەردەگرێت () کە تەنیا زیاد دەبێت، بۆ ئەوەی هەموو کەس بتوانێت ڕێک بڵێت کام تاقی کردەوە.
Teams build on a clean build server from a fresh copy of the repository, not on one developer's laptop, so “it works on my machine” cannot hide a missing file or a different library version. Running build and tests automatically on every push is continuous integration — see Continuous integration.
تیمەکان لەسەر پاک و لە کۆپییەکی نوێی دەکەن، نەک لەسەر لاپتۆپی یەک ، بۆ ئەوەی «لەسەر ئامێرەکەی من کار دەکات» نەتوانێت ون یان جیاوازی بشارێتەوە. جێبەجێکردنی خۆکاری و تاقیکردنەوەکان لەگەڵ هەر — بڕوانە پێکەوەبەستنی بەردەوام.
Builds: from source code to an artifactبیلد: لە کۆدی سەرچاوەوە بۆ بەرهەمی بیلد
Build Bazaar Cart 1.0.0 into one fileBazaar Cart 1.0.0 بکە بە یەک فایل
Python's standard library can turn a folder of code into one runnable file with zipapp. By 1.0.0, cart.py has a main() function that prints a sample order (made-up prices, in IQD). The build copies only the files that ship into build/app/, packs them, runs the result and looks inside:
ستانداردی Python دەتوانێت بە zipapp فۆڵدەرێکی کۆد بکات بە یەک کارپێکراو. لە 1.0.0ـدا cart.py main()ـی هەیە کە داواکارییەکی نموونە چاپ دەکات (نرخی دروستکراو، بە دینار). تەنیا ئەو دەنێردرێن کۆپی دەکات بۆ build/app/، دەیانپێچێتەوە، ئەنجامەکە جێبەجێ دەکات و سەیری ناوی دەکات:
mkdir -p build/app dist && cp prices.py cart.py storage.py build/app/
python3.13 -m zipapp build/app -m "cart:main" -p "/usr/bin/env python3" -o dist/bazaar_cart-1.0.0.pyz
python3.13 dist/bazaar_cart-1.0.0.pyz
python3.13 -m zipfile -l dist/bazaar_cart-1.0.0.pyz$ mkdir -p build/app dist && cp prices.py cart.py storage.py build/app/ $ python3.13 -m zipapp build/app -m "cart:main" -p "/usr/bin/env python3" -o dist/bazaar_cart-1.0.0.pyz $ python3.13 dist/bazaar_cart-1.0.0.pyz Bazaar Cart 1.0.0 walnuts 500 g 9,000 IQD sumac 350 g 2,750 IQD black tea 250 g 3,500 IQD Goods total 15,250 IQD Delivery 3,000 IQD To pay 18,250 IQD $ python3.13 -m zipfile -l dist/bazaar_cart-1.0.0.pyz File Name Modified Size cart.py 2026-11-10 03:33:22 673 prices.py 2026-11-10 03:33:22 919 storage.py 2026-11-10 03:33:22 290 __main__.py 2026-11-10 03:33:22 48
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1
Copy only the files that ship: no tests, no
.git, no secrets.تەنیا ئەو دەنێردرێن کۆپی بکە: نە تاقیکردنەوە، نە
.git، نە نهێنی.- Lineدێڕی 2
-mwrites a__main__.pythat callscart.main();-padds a first line so the file runs by itself on Mac and Linux;-onames the artifact with its version.-m__main__.pyدەنووسێت کە بانگیcart.main()دەکات؛-pدێڕێکی یەکەم زیاد دەکات بۆ ئەوەی لەسەر Mac و Linux بە تەنیا کار بکات؛-oناوی بە دادەنێت.- Lineدێڕی 3
Run the artifact. In the output, 350 g of sumac shows 2,750 IQD — rule R1 says round up, so it should be 3,000.
جێبەجێ بکە. لە دەرئەنجامەکەدا 350 گرام سماق 2,750 دینار پیشان دەدات — یاسای R1 دەڵێت بەرزی بکەرەوە، بۆیە دەبێت 3,000 بێت.
- Lineدێڕی 4
List the zip: the three modules plus the
__main__.pythat-mwrote.ناوەڕۆکی زیپەکە لیست بکە: سێ لەگەڵ ئەو
__main__.pyـیەی کە-mنووسیویەتی.
Look at the sumac line: Bazaar Cart 1.0.0 was released with a rounding bug. A day before the release Karwan had “simplified” round_up_250() to amount // 250 * 250, which rounds down. The fix is a PATCH, 1.0.1, and a new build of 1.0.1 shows 3,000 IQD for the sumac and 18,500 IQD to pay. How tests catch such bugs is in Every bug gets a test. In the course project you build and release 1.0.0 again, this time with tests that stop this bug.
سەیری دێڕی سماقەکە بکە: Bazaar Cart 1.0.0 بە بەرزکردنەوەی نرخەوە بڵاو کرایەوە. ڕۆژێک پێش کاروان round_up_250()ـی «سادە کردبووەوە» بۆ amount // 250 * 250، کە نرخەکە بەرەو خوارەوە دەبات. چاککردنەوەکە ، 1.0.1 و نوێی 1.0.1 بۆ سماقەکە 3,000 دینار و بۆ پارەدان 18,500 دینار پیشان دەدات. تاقیکردنەوەکان چۆن ئەم جۆرە دەگرن لە هەر باگێک تاقیکردنەوەیەک وەردەگرێتـدایە. لە پڕۆژەی خولەکە جارێکی تر 1.0.0 دروست دەکەیت و بڵاوی دەکەیتەوە، ئەم جارە لەگەڵ تاقیکردنەوەی وا کە ڕێگە لەم دەگرن.
Builds: from source code to an artifactبیلد: لە کۆدی سەرچاوەوە بۆ بەرهەمی بیلد
Debug builds and release buildsبیلدی پشکنین و بیلدی بڵاوکردنەوە
Many tools make two kinds of build. A debug build keeps extra checks and helpers for developers; a release build is optimised for users. Flutter's three modes are explained in Debug, profile and release mode. Python has a small version of the same idea: python -O removes every assert statement.
زۆر ئامراز دوو جۆر دروست دەکەن. debug پشکنین و یارمەتیدەری زیادە بۆ دەهێڵێتەوە؛ release بۆ باشتر کراوە. سێ دۆخەکەی Flutter لە دۆخی debug، profile و release ڕوون کراونەتەوە. Python وەشانێکی بچووکی هەمان بیرۆکەی هەیە: python -O هەموو دەستەواژەیەکی assert لادەبات.
Here is Karwan's buggy delivery.py from the requirements lesson, run both ways:
ئەمە delivery.pyـەکەی کاروانە کە تێدایە، لە وانەی پێداویستییەکان، بە هەردوو شێوە جێبەجێ کراوە:
python3.13 delivery.py
python3.13 -O delivery.py$ python3.13 delivery.py
Traceback (most recent call last):
File "~/se/bazaar-cart/delivery.py", line 17, in <module>
assert delivery_fee(50_000) == 0 # exactly at the limit: free
^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError
$ python3.13 -O delivery.py
R4: all three checks passedWith -O the checks are gone and the wrong fee passes silently. So assert is for checking your own assumptions while you develop and test — rules that must always hold, such as R2's 100 to 10,000 g, need a real if … raise ValueError.
بە -O پشکنینەکان نامێنن و کرێیە هەڵەکە بە بێدەنگی تێدەپەڕێت. بۆیە assert بۆ پشکنینی گریمانەکانی خۆتە لە کاتی گەشەپێدان و تاقیکردنەوەدا — ئەو یاسایانەی دەبێت هەمیشە جێبەجێ بن، وەک 100 تا 10,000 گرامی R2، پێویستیان بە if … raise ValueErrorـی ڕاستەقینەیە.
Releases and Git tagsوەشانە بڵاوکراوەکان و تاگەکانی Git
A release must point to the exact code it was built from. A Git tag gives one commit a permanent name. You met a quick, lightweight tag in Branches and merging; for releases Pro Git recommends annotated tags (-a), which also store who tagged, when, and a message. Tag names usually start with v, but the version itself is 1.0.0.
دەبێت ئاماژە بە ڕێک ئەو کۆدە بکات کە لێیەوە کراوە. ناوێکی هەمیشەیی دەدات بە یەک . تاگێکی خێرا و سووکـت لە لق و بەیەککردنـدا بینی؛ بۆ ، Pro Git پێشنیاری تاگی ڕوونکراوە (annotated، -a) دەکات کە هەروەها تۆمار دەکات کێ و کەی تاگی کردووە لەگەڵ پەیامێک. ناوی زۆرجار بە v دەست پێدەکەن، بەڵام خودی 1.0.0ـە.
git tag -a v1.0.0 -m "Bazaar Cart 1.0.0: first release"
git tag
git show --no-patch v1.0.0$ git tag -a v1.0.0 -m "Bazaar Cart 1.0.0: first release"
$ git tag
v0.1.0
v0.2.0
v0.3.0
v1.0.0
$ git show --no-patch v1.0.0
tag v1.0.0
Tagger: Aram <aram@example.com>
Date: Sat Nov 7 09:45:00 2026 +0300
Bazaar Cart 1.0.0: first release
commit fa43979974ec1897ac12c49d1cea557d59029244
Author: Aram <aram@example.com>
Date: Sat Nov 7 09:30:00 2026 +0300
Prepare release 1.0.0A shortened copy of Bazaar Cart's history, so the hashes differ from the Git lessons.
کۆپییەکی کورتکراوەی مێژووی Bazaar Cartـە، بۆیە هاشەکان لەگەڵ وانەکانی Git جیاوازن.
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1
-amakes an annotated tag;-mis its message.-aتاگێکی ڕوونکراوە دروست دەکات؛-mپەیامەکەیەتی.- Lineدێڕی 3
git showprints the tag's own information (who, when, why), then the commit it points to — the code of release 1.0.0.git showسەرەتا زانیاریی خودی (کێ، کەی، بۆچی) چاپ دەکات، دواتر ئەو ئاماژەی پێدەکات — کۆدی 1.0.0.
Releases and Git tagsوەشانە بڵاوکراوەکان و تاگەکانی Git
Between releases, and sharing tagsلە نێوان وەشانە بڵاوکراوەکاندا و هاوبەشکردنی تاگەکانی Git
Two days later Shilan commits the rounding fix. git describe names any commit from the nearest tag: v1.0.0-1-g216e807 means one commit after v1.0.0, at commit 216e807. Build numbers and bug reports often use such names. After the team tags 1.0.1, the log reads like the version story:
دوو ڕۆژ دواتر شیلان چاککردنەوەی بەرزکردنەوەکە دەکات. git describe هەر لە نزیکترین ناو دەنێت: v1.0.0-1-g216e807 واتە یەک دوای v1.0.0، لە 216e807. و ڕاپۆرتی زۆرجار ناوی لەم جۆرە بەکار دەهێنن. دوای ئەوەی تیمەکە 1.0.1 تاگ دەکات، وەک چیرۆکی دەخوێندرێنەوە:
git commit -am "Round line prices up again (R1)"
git describe
git tag -a v1.0.1 -m "Bazaar Cart 1.0.1: rounding fix"
git describe
git log --oneline --decorate$ git commit -am "Round line prices up again (R1)" $ git describe v1.0.0-1-g216e807 $ git tag -a v1.0.1 -m "Bazaar Cart 1.0.1: rounding fix" $ git describe v1.0.1 $ git log --oneline --decorate 216e807 (HEAD -> main, tag: v1.0.1) Round line prices up again (R1) fa43979 (tag: v1.0.0) Prepare release 1.0.0 7e8effd Simplify round_up_250() a2357f5 (tag: v0.3.0) Store products in SQLite 0f71146 (tag: v0.2.0) Add delivery_fee() and show the fee in cart.py 989b6ba (tag: v0.1.0) Add line price calculation
Tags do not travel with a normal git push: after pushing main, the team's shared repository (remotes and pushing) still lists no tags. Push them by name:
لەگەڵ git pushـی ئاسایی ناڕۆن: دوای main، هاوبەشی تیمەکە (کۆگاکانی کۆدی دوور و پوش) هێشتا هیچ تاگێک پیشان نادات. بە ناو بکە:
git push -q origin main
git ls-remote --tags origin
git push origin v1.0.0 v1.0.1$ git push -q origin main $ git ls-remote --tags origin $ git push origin v1.0.0 v1.0.1 To ~/se/server/bazaar-cart.git * [new tag] v1.0.0 -> v1.0.0 * [new tag] v1.0.1 -> v1.0.1
Releases and Git tagsوەشانە بڵاوکراوەکان و تاگەکانی Git
A changelog for peopleتۆماری گۆڕانکارییەکان بۆ خەڵک
A changelog lists the notable changes of every version for people (Keep a Changelog 1.1.0): the newest version first, dates as YYYY-MM-DD, an Unreleased section on top for what is coming, and changes grouped as Added, Changed, Deprecated, Removed, Fixed and Security. It is not a copy of git log: commit messages are for developers; the changelog tells users what changed for them.
گۆڕانکارییە گرنگەکانی هەموو بۆ خەڵک ڕیز دەکات (Keep a Changelog 1.1.0): نوێترین لە سەرەوە، ڕێکەوت بە شێوەی YYYY-MM-DD، بەشێکی Unreleased لە سەرەوە بۆ ئەوەی دێت و گۆڕانکارییەکان بە گرووپی Added، Changed، Deprecated، Removed، Fixed و Security. کۆپیی git log نییە: پەیامی بۆ ؛ بە دەڵێت چی بۆ ئەوان گۆڕاوە.
CHANGELOG.mdـی Bazaar Cart لە کاتێکدا 1.1.0 دروست دەکرێتCHANGELOG.mdTEXT# Changelog
All notable changes to Bazaar Cart are written in this file.
Bazaar Cart follows Semantic Versioning.
## [Unreleased]
### Added
- 5 % off goods totals of 100,000 IQD or more (R5).
## [1.0.1] - 2026-11-09
### Fixed
- Line prices are rounded up to the next 250 IQD again (R1).
1.0.0 rounded some down: 350 g of sumac cost 2,750 instead of 3,000.
## [1.0.0] - 2026-11-07
### Added
- Order lines priced per kg and rounded up to 250 IQD (R1, R2).
- Never sell more than the stock (R3).
- Delivery inside Sulaimani: 3,000 IQD, free from 50,000 IQD (R4).
- Products stored in an SQLite database.The “What's new” text in an app store (how an app reaches the store) is a short, friendly version of the same list. Fuller release notes also name known problems and what the software needs to run.
دەقی «What's new» لە (ئەپێک چۆن دەگاتە فرۆشگاکە) وەشانێکی کورت و دۆستانەی هەمان لیستە. تێبینییە تەواوەکانی کێشە ناسراوەکان و ئەوەی بۆ کارکردن پێویستیەتیش دەڵێن.
Releases and Git tagsوەشانە بڵاوکراوەکان و تاگەکانی Git
Continuous delivery and continuous deploymentگەیاندنی بەردەوام و خستنەکاری بەردەوام
Once building, testing and packaging are automatic, a team can keep its software always ready to release. In continuous delivery (Martin Fowler), every change that passes the pipeline could go to production, and a person decides when — with one button. Continuous deployment goes one step further: every change that passes all the checks reaches users automatically.
کاتێک ، تاقیکردنەوە و پێچانەوە خۆکار بن، تیمێک دەتوانێت هەمیشە ئامادەی بڵاوکردنەوە بهێڵێتەوە. لە ـدا (مارتن فاولەر)، هەر گۆڕانکارییەک کە لە زنجیرەکە دەردەچێت دەتوانێت بڕوات بۆ بەکارهێنانی ڕاستەقینە و کەسێک بڕیار دەدات کەی — بە یەک . هەنگاوێک زیاتر دەڕوات: هەر گۆڕانکارییەک کە لە هەموو پشکنینەکان دەردەچێت خۆکارانە دەگاتە .
Bazaar Cart uses continuous delivery: Soran does not want a new version on a busy Thursday evening, so Aram presses the button on Saturday morning. Apps on phones also pass the store's checks after upload, so they never reach every phone the same minute.
Bazaar Cart بەکار دەهێنێت: سۆران نوێ لە ئێوارەیەکی قەرەباڵغی پێنجشەممەدا ناوێت، بۆیە ئارام بەیانیی شەممە دادەگرێت. مۆبایلیش دوای بە پشکنینەکانی تێدەپەڕن، بۆیە هەرگیز لە هەمان خولەکدا ناگەنە هەموو مۆبایلێک.
Common mistakesهەڵە باوەکان
from semver import semver_key
tag = "v1.0.0" # a Git tag name
print(semver_key(tag))Traceback (most recent call last):
File "~/se/versions/tag_check.py", line 4, in <module>
print(semver_key(tag))
~~~~~~~~~~^^^^^
File "~/se/versions/semver.py", line 15, in semver_key
raise ValueError(f"not a semantic version: {version!r}")
ValueError: not a semantic version: 'v1.0.0'Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
Fix:
semver_key(tag.removeprefix("v"))gives(1, 0, 0, (1,)).چارەسەر:
semver_key(tag.removeprefix("v"))دەدات(1, 0, 0, (1,)).
Exercisesڕاهێنانەکان
Bazaar Cart is at 1.1.0. For each change on its own, write the next version: (a) the honey price was shown per 100 g by mistake — fixed; (b) a new function favourites(); (c) the old function total(), which the website still calls, is removed; (d) a faster database query that gives the same results; (e) place_order(user_id) is marked deprecated and place_order(customer) is added; (f) a library Bazaar Cart uses is updated to fix a security bug, and Bazaar Cart's own API does not change.
Bazaar Cart لە 1.1.0ـدایە. بۆ هەر گۆڕانکارییەک بە جیا، داهاتوو بنووسە: (a) نرخی هەنگوین بە هەڵە بۆ 100 گرام پیشان دەدرا — چاک کرا؛ (b) نوێی favourites()؛ (c) کۆنەکەی total()، کە ماڵپەڕەکە هێشتا بانگی دەکات، لادەبرێت؛ (d) پرسیارێکی خێراتری کە هەمان ئەنجام دەدات؛ (e) place_order(user_id) وەک نیشان دەکرێت و place_order(customer) زیاد دەکرێت؛ (f) کە Bazaar Cart بەکاری دەهێنێت بۆ چاککردنی نوێ دەکرێتەوە و خودی Bazaar Cart ناگۆڕێت.
Show answerوەڵامەکە پیشان بدە
- (a) 1.1.1 — a bug fix.
- (b) 1.2.0 — a new feature.
- (c) 2.0.0 — removing a function others call is breaking.
- (d) 1.1.1 — nothing changes for callers.
- (e) 1.2.0 — a deprecation and an addition are MINOR.
- (f) 1.1.1 — semver's FAQ: a dependency update that fixes a bug, with no API change, is a patch.
- (a) 1.1.1 — چاککردنەوەی .
- (b) 1.2.0 — تایبەتمەندیی نوێ.
- (c) 2.0.0 — لابردنی کە ئەوانی تر بانگی دەکەن شکێنەرە.
- (d) 1.1.1 — هیچ شتێک بۆ بانگکەران ناگۆڕێت.
- (e) 1.2.0 — نیشانکردنی و زیادکردن MINORـن.
- (f) 1.1.1 — پرسیارە باوەکانی semver: کە چاک دەکات بێ گۆڕینی ، پینەیە.
Sort from oldest to newest: 2.0.0-rc.1, 1.10.0, 2.0.0, 1.9.3, 2.0.0-beta, 1.10.0+build.5. Which two have the same precedence?
لە کۆنترینەوە بۆ نوێترین ڕیزیان بکە: 2.0.0-rc.1، 1.10.0، 2.0.0، 1.9.3، 2.0.0-beta، 1.10.0+build.5. کام دووانیان هەمان پێشینەیییان هەیە؟
Show answerوەڵامەکە پیشان بدە
1.9.3 < 1.10.0 = 1.10.0+build.5 < 2.0.0-beta < 2.0.0-rc.1 < 2.0.01.10.0 and 1.10.0+build.5 have the same precedence, because build metadata is ignored. "beta" comes before "rc" in ASCII order.
1.10.0 و 1.10.0+build.5 هەمان پێشینەیییان هەیە، چونکە زانیاریی پشتگوێ دەخرێت. «beta» بە ڕیزی ASCII پێش «rc» دێت.
Hana's Hawler Ride app has version: 1.4.2+17 in pubspec.yaml. Write the line for (1) a bug-fix release, then (2) a release with a new feature after it.
Hawler Rideـی هانا لە pubspec.yamlـدا version: 1.4.2+17ـی هەیە. دێڕەکە بنووسە بۆ (1) چاککردنەوە، دواتر (2) بە تایبەتمەندییەکی نوێ دوای ئەوە.
Show answerوەڵامەکە پیشان بدە
version: 1.4.3+18 # (1) PATCH up, build number up
version: 1.5.0+19 # (2) MINOR up, PATCH reset, build number upThe build number never goes back, even when MINOR or MAJOR resets other numbers.
هەرگیز ناگەڕێتەوە دواوە، تەنانەت کاتێک MINOR یان MAJOR ژمارەکانی تر سفر دەکاتەوە.
Lana's timetable app (0.8.0) is used every day by 300 students, and two other school apps read its timetable through its API. Should Lana release 1.0.0? Explain in two sentences.
خشتەی لانا (0.8.0) هەموو ڕۆژێک 300 قوتابی بەکاری دەهێنن و دوو تری قوتابخانە لە ڕێگەی خشتەکەی دەخوێننەوە. ئایا لانا دەبێت 1.0.0 بڵاو بکاتەوە؟ بە دوو ڕستە ڕوونی بکەرەوە.
Show answerوەڵامەکە پیشان بدە
Yes. The app is used in production and other programs depend on its API, so semver says it should already be 1.0.0; from then on a breaking change needs 2.0.0, which protects the two other apps.
بەڵێ. بە ڕاستی بەکار دەهێنرێت و تر پشت بە دەبەستن، بۆیە semver دەڵێت دەبوو پێشتر 1.0.0 بووایە؛ لەوە بەدواوە پێویستی بە 2.0.0 دەبێت، کە دوو تر دەپارێزێت.
Bazaar Cart 1.1.0 is released on 2026-11-20 with the R5 discount. Write its CHANGELOG entry and say what happens to the Unreleased section.
Bazaar Cart 1.1.0 لە 2026-11-20 لەگەڵ داشکانی R5 بڵاو دەکرێتەوە. بەشەکەی لە بنووسە و بڵێ چی بە بەشی Unreleased دەکرێت.
Show answerوەڵامەکە پیشان بدە
## [Unreleased]
## [1.1.0] - 2026-11-20
### Added
- 5 % off goods totals of 100,000 IQD or more,
rounded up to 250 IQD (R5).The entry moves from Unreleased into the new 1.1.0 section, and Unreleased starts empty again.
بەشەکە لە Unreleasedـەوە دەچێتە بەشی نوێی 1.1.0 و Unreleased دیسان بە بەتاڵی دەست پێدەکاتەوە.
Write the Git commands to tag the current commit as release 1.1.0 with a message, send the tag to origin, and check the name of the current commit.
فەرمانەکانی Git بنووسە بۆ تاگکردنی ئێستا وەک 1.1.0 لەگەڵ پەیامێک، ناردنی بۆ origin و پشکنینی ناوی ئێستا.
Show answerوەڵامەکە پیشان بدە
git tag -a v1.1.0 -m "Bazaar Cart 1.1.0: 5 % discount (R5)"
git push origin v1.1.0
git describe # prints v1.1.0 on the tagged commitSummaryپوختە
- Version = a numbered state; build = turning source into a runnable artifact (with a build number); release = a version given to people outside the team.
- Semver 2.0.0: MAJOR for breaking changes, MINOR for compatible features and deprecations, PATCH for fixes; the number that goes up resets those to its right; released contents never change.
- 0.y.z = anything may change; 1.0.0 defines the public API — release it when people depend on it. It does not mean bug-free.
- Pre-releases (
-alpha,-beta.2,-rc.1) rank below the release; build metadata (+57) is ignored. Compare versions as numbers, never as text. - Other schemes: CalVer (Ubuntu 26.04), PEP 440 (
1.0.0rc1), Java LTS; Android's versionName + versionCode, Flutter'sversion: 1.0.1+2(the+2is the build number). - Constraints (
^1.2.3,~=1.4.5) accept compatible updates; a lock file pins exact versions. - Release with an annotated tag, push the tag, keep a changelog for people; continuous delivery keeps every change ready, continuous deployment ships it automatically.
- = دۆخێکی ژمارەدار؛ = گۆڕینی بۆ کارپێکراو (بە )؛ = کە دەدرێت بە خەڵکی دەرەوەی تیم.
- semver 2.0.0: MAJOR بۆ ، MINOR بۆ تایبەتمەندیی گونجاو و ، PATCH بۆ چاککردنەوە؛ ئەو ژمارەیەی زیاد دەبێت ژمارەکانی لای ڕاستی سفر دەکاتەوە؛ ناوەڕۆکی بڵاوکراوە هەرگیز ناگۆڕێت.
- 0.y.z = هەر شتێک لەوانەیە بگۆڕێت؛ 1.0.0 گشتی دیاری دەکات — بڵاوی بکەرەوە کاتێک خەڵک پشتی پێ دەبەستن. واتای بێ نییە.
- (
-alpha،-beta.2،-rc.1) لە خوار ؛ زانیاریی (+57) پشتگوێ دەخرێت. وەک ژمارە بەراورد بکە، هەرگیز وەک دەق. - شێوازەکانی تر: CalVer (Ubuntu 26.04)، PEP 440 (
1.0.0rc1)، LTSـی Java؛ versionName + versionCodeـی Android،version: 1.0.1+2ـی Flutter (+2). - (
^1.2.3،~=1.4.5) گونجاو وەردەگرن؛ ورد دەچەسپێنێت. - بە تاگی ڕوونکراوە بڵاو بکەرەوە، بکە، بۆ خەڵک بنووسە؛ هەموو گۆڕانکارییەک ئامادە دەهێڵێتەوە، خۆکارانە دەینێرێت.
Next: make the computer check every build for you — Automated testing.
داهاتوو: وا بکە کۆمپیوتەر هەموو بۆت بپشکنێت — تاقیکردنەوەی خۆکار.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Automated Testing: Code That Checks Your Codeتاقیکردنەوەی خۆکار: کۆدێک کە کۆدەکەت دەپشکنێت
Related lecturesوانە پەیوەندیدارەکان
- Branches and Merging: Working on Many Things at Onceلقەکان و بەیەککردن: کارکردن لەسەر چەند شتێک لە یەک کاتدا
- GitHub and Teamwork: Remotes, Pull Requests and IssuesGitHub و کاری تیمی: کۆگاکانی کۆدی دوور، داواکارییەکانی بەیەککردن و ئیشووەکان
- Automated Testing: Code That Checks Your Codeتاقیکردنەوەی خۆکار: کۆدێک کە کۆدەکەت دەپشکنێت
- Requirements and Design: Deciding What to Buildپێداویستییەکان و دیزاین: بڕیاردان لەسەر ئەوەی چی دروست بکەین
- Course Project: Ship Bazaar Cart 1.0.0پڕۆژەی خولەکە: Bazaar Cart 1.0.0 بڵاو بکەرەوە
- Building Softwareدروستکردنی نەرمەواڵە
- Setting Up Flutter and Your First Projectئامادەکردنی Flutter و یەکەم پڕۆژەکەت
- Welcome to Java: the JDK, the JRE and the JVMبەخێربێیت بۆ Java: JDK، JRE و JVM
- Mobile Apps and App Storesئەپەکانی مۆبایل و فرۆشگاکانی ئەپ
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
- Semantic Versioning 2.0.0 (semver.org): rules 3–11 and FAQ
- Python Packaging User Guide: Version specifiers (PEP 440) — pre-, post- and dev-releases, local labels, ~= compatible release
- calver.org: Calendar Versioning
- Ubuntu release cycle (26.04 LTS, April 2026)
- Android Developers: Version your app (versionCode, versionName)
- Flutter docs: Build and release an Android app (version and build number)
- Dart: Glossary of package terms (lockfile)
- Python docs: zipapp — Manage executable Python zip archives
- Python docs: Command line and environment (-O)
- Pro Git, 2.6 Git Basics — Tagging
- Keep a Changelog 1.1.0
- Martin Fowler: ContinuousDelivery (2013)
- SWEBOK Guide V4.0a (IEEE Computer Society, 2024): Software Configuration Management KA §6, software building and release management
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.