如何維護更新日誌

更新日誌絕對不應該只是 git log 的堆砌物

Version 1.0.0
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.0.0] - 2017-06-20
### Added
- New visual identity by [@tylerfortune8](https://github.com/tylerfortune8).
- Version navigation.
- Links to latest released version in previous versions.
- "Why keep a changelog?" section.
- "Who needs a changelog?" section.
- "How do I make a changelog?" section.
- "Frequently Asked Questions" section.
- New "Guiding Principles" sub-section to "How do I make a changelog?".
- Simplified and Traditional Chinese translations from [@tianshuo](https://github.com/tianshuo).
- German translation from [@mpbzh](https://github.com/mpbzh) & [@Art4](https://github.com/Art4).
- Italian translation from [@azkidenz](https://github.com/azkidenz).
- Swedish translation from [@magol](https://github.com/magol).
- Turkish translation from [@karalamalar](https://github.com/karalamalar).
- French translation from [@zapashcanon](https://github.com/zapashcanon).
- Brazilian Portugese translation from [@Webysther](https://github.com/Webysther).
- Polish translation from [@amielucha](https://github.com/amielucha) & [@m-aciek](https://github.com/m-aciek).
- Russian translation from [@aishek](https://github.com/aishek).
- Czech translation from [@h4vry](https://github.com/h4vry).
- Slovak translation from [@jkostolansky](https://github.com/jkostolansky).
- Korean translation from [@pierceh89](https://github.com/pierceh89).
- Croatian translation from [@porx](https://github.com/porx).
- Persian translation from [@Hameds](https://github.com/Hameds).
- Ukrainian translation from [@osadchyi-s](https://github.com/osadchyi-s).

### Changed
- Start using "changelog" over "change log" since it's the common usage.
- Start versioning based on the current English version at 0.3.0 to help
translation authors keep things up-to-date.
- Rewrite "What makes unicorns cry?" section.
- Rewrite "Ignoring Deprecations" sub-section to clarify the ideal
  scenario.
- Improve "Commit log diffs" sub-section to further argument against
  them.
- Merge "Why can’t people just use a git log diff?" with "Commit log
  diffs"
- Fix typos in Simplified Chinese and Traditional Chinese translations.
- Fix typos in Brazilian Portuguese translation.
- Fix typos in Turkish translation.
- Fix typos in Czech translation.
- Fix typos in Swedish translation.
- Improve phrasing in French translation.
- Fix phrasing and spelling in German translation.

### Removed
- Section about "changelog" vs "CHANGELOG".

## [0.3.0] - 2015-12-03
### Added
- RU translation from [@aishek](https://github.com/aishek).
- pt-BR translation from [@tallesl](https://github.com/tallesl).
- es-ES translation from [@ZeliosAriex](https://github.com/ZeliosAriex).

## [0.2.0] - 2015-10-06
### Changed
- Remove exclusionary mentions of "open source" since this project can
benefit both "open" and "closed" source projects equally.

## [0.1.0] - 2015-10-06
### Added
- Answer "Should you ever rewrite a change log?".

### Changed
- Improve argument against commit logs.
- Start following [SemVer](https://semver.org) properly.

## [0.0.8] - 2015-02-17
### Changed
- Update year to match in every README example.
- Reluctantly stop making fun of Brits only, since most of the world
  writes dates in a strange way.

### Fixed
- Fix typos in recent README changes.
- Update outdated unreleased diff link.

## [0.0.7] - 2015-02-16
### Added
- Link, and make it obvious that date format is ISO 8601.

### Changed
- Clarified the section on "Is there a standard change log format?".

### Fixed
- Fix Markdown links to tag comparison URL with footnote-style links.

## [0.0.6] - 2014-12-12
### Added
- README section on "yanked" releases.

## [0.0.5] - 2014-08-09
### Added
- Markdown links to version tags on release headings.
- Unreleased section to gather unreleased changes and encourage note
keeping prior to releases.

## [0.0.4] - 2014-08-09
### Added
- Better explanation of the difference between the file ("CHANGELOG")
and its function "the change log".

### Changed
- Refer to a "change log" instead of a "CHANGELOG" throughout the site
to differentiate between the file and the purpose of the file — the
logging of changes.

### Removed
- Remove empty sections from CHANGELOG, they occupy too much space and
create too much noise in the file. People will have to assume that the
missing sections were intentionally left out because they contained no
notable changes.

## [0.0.3] - 2014-08-09
### Added
- "Why should I care?" section mentioning The Changelog podcast.

## [0.0.2] - 2014-07-10
### Added
- Explanation of the recommended reverse chronological release ordering.

## [0.0.1] - 2014-05-31
### Added
- This CHANGELOG file to hopefully serve as an evolving example of a
  standardized open source project CHANGELOG.
- CNAME file to enable GitHub Pages custom domain
- README now contains answers to common questions about CHANGELOGs
- Good examples and basic guidelines, including proper date formatting.
- Counter-examples: "What makes unicorns cry?"

[Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.3.0...v1.0.0
[0.3.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.8...v0.1.0
[0.0.8]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.7...v0.0.8
[0.0.7]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.6...v0.0.7
[0.0.6]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.5...v0.0.6
[0.0.5]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.4...v0.0.5
[0.0.4]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.3...v0.0.4
[0.0.3]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.2...v0.0.3
[0.0.2]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.1...v0.0.2
[0.0.1]: https://github.com/olivierlacan/keep-a-changelog/releases/tag/v0.0.1

更新日誌是什麼?

更新日誌(Changelog)是個記錄專案演進版本間的差異,以時間倒敘、由人工攥寫的列表。

為什麼需要提供更新日誌?

為了讓使用者和開發人員更簡單明確地了解各個版本之間有著哪些改動。

哪些人需要更新日誌?

大家都需要更新日誌。無論是使用者還是開發者,軟體最終的用戶都會在意軟體包含了什麼。當軟體更新了,大家會希望知道改了什麼、為什麼要改。

如何寫出高品質的日誌?

指導原則

  • 日誌是寫給「人」看的,不是機器。
  • 每個版本都應該有獨立的進入點。
  • 相同類型的改動應分組放置。
  • 版本與章節應「可連結化」。
  • 新版本總是寫在前面。
  • 每個版本都該註記發佈日期。
  • 版本命名應遵守語意化版本格式。

改動類型

  • Added 當增加了新功能。
  • Changed 當更動了既有的功能。
  • Deprecated 當功能將在近期被移除。
  • Removed 當移除了現有的功能。
  • Fixed 當修復了某些錯誤。
  • Security 當增進了安全性漏洞。

如何提升維護更新日誌的效率?

在日誌上方使用 Unreleased 區塊記錄即將發佈的更新內容。

這麼做能夠:

  • 讓大家知道在未來的版本中可能會有哪些改動。
  • 發佈新版本時,直接將 Unreleased 移到新版本的區塊就完成了 ヾ(*´ω`*)ノ

難道日誌能寫得很糟嗎?

當然。下面有些糟糕的範例:

🚫 直接使用 git log

使用 git log 作為更新日誌絕對不是個好主意:git log 充滿了各種無意義的訊息,像 merge commits 、亂七八糟的提交訊息、文件更新等。

Commits 的目的應該是記錄原始碼的演化過程。有些項目會清理 commits,有些卻不會。

更新日誌的目的則是記錄那些值得一提的改動,經常涵蓋多個 commits,最終目的仍是讓使用者一目了然。

🚫 忽略 Deprecations

當使用者升級版本時,他應該要能預先知道哪些環節可能會出問題。理想的情形下,應該讓使用者有空間能預先升級即將被棄用的功能;待替換掉棄用功能之後,再升級至棄用功能被真正移除的版本。

即使不這麼做,也要在更新日誌中列出棄用的、移除的、或是任何可能導致程式碼失效的重大改動。

🚫 易混淆的日期格式

在世界的每個角落,不同區域有著不同的時間格式,找到讓大家都滿意的日期格式不是件簡單的事。使用像 2017-07-17 的格式能清楚傳達日期、不易與其他日期格式混淆,同時也遵守 ISO 標準,因此推薦使用像這樣的日期格式。

常見問題

有沒有標準格式可以參考呢?

並沒有。雖然有 GNU 更新日誌指南 以及只有兩段長的 GNU - The NEWS File 指南(括弧笑),但這些並不足以稱為「標準」。

這項專案的宗旨在於提供一個 更好的更新日誌範例,源於觀察開源社群中優秀的實際案例,把它們蒐集在一起。

歡迎各位提供有建設性的建議和批評。

更新日誌的檔案名稱應該是?

通常使用 CHANGELOG.md。也有用 HISTORYNEWS、或是 RELEASES 的例子。

或許你認為取什麼名字並不是件多麼重要的事,但為什麼要讓只是想看日誌的使用者不容易找到它呢?

那麼 GitHub Releases 呢?

這是個好問題。GitHub Releases 能手動在簡單的 git tag(如 v1.0.0) 上附加豐富的版本資訊,也能把附帶的 tag messages 轉換成漂亮的日誌格式。

GitHub Releases 產生的日誌只能在 GitHub 上瀏覽,雖然 GitHub Releases 能做出接近本專案範例的日誌格式,但這會增加些許與 GitHub 的相依性。

現行的 GitHub Releases 畢竟不像典型的大寫文件(READMECONTRIBUTING 之類的),按理說會增加使用者找到的難度。另外還有個小問題,目前 GitHub Releases 頁面上並沒有提供兩版版本之間 commit logs 的連結。

更新日誌能被自動生成嗎?

非常困難,各式各樣的提交訊息和檔案名稱難以完全掌握。

另外,有些開源專案使用由 Gemnasium 團隊開發的 Vandamme 轉換更新日誌,或許可以當作參考。

那麼被撤下的版本呢?

因為重大漏洞或安全性問題而被撤下(unpublished)的版本通常不會出現在日誌裡,但建議仍然記錄下來。你可以這樣記錄它們:

## 0.0.5 - 2014-12-13 [YANKED]

其中 [YANKED] 標記應該和原因顯眼地標示在一起,讓使用者注意到它是最重要的事。此外,用中括弧能讓轉換用的程式更容易辨認它們。

可以更改過去版本的日誌內容嗎?

當然可以,總是會有好的原因來改善以往寫下的日誌。我也時常發 pull request 給更新日誌不齊全的開源專案。

偶爾會發現自己遺漏了某項重大更新的紀錄,很明顯你應該補齊它們。

我能做些什麼嗎?

這份文件並不是《真理》,而是我經過深思熟慮、遵循蒐集到的資訊和範例之後提出的建議。

源於我期望社群能達到共識,我相信討論的過程與結果一樣重要。

所以,加入我們吧 ٩(。・ω・。)و

訪談

我在 The Changelog podcast 上講述了為什麼維護者與協作者應該在意更新日誌,以及建立這項專案背後的契機。