mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Replace Towncrier with GitHub releases + labels. (#2966)
* Set up GitHub generated release notes. * Remove Towncrier from the release script. * Add changelog failures for Labels with Danger and stop requesting a changelog file. * Update changelog documentation.
This commit is contained in:
parent
567f22b806
commit
82823c94ce
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,8 +1,8 @@
|
||||
### Pull Request Checklist
|
||||
|
||||
- [ ] I read the [contributing guide](https://github.com/element-hq/element-ios/blob/develop/CONTRIBUTING.md)
|
||||
- [ ] Pull request contains a [changelog file](https://github.com/matrix-org/matrix-ios-sdk/blob/develop/CONTRIBUTING.md#changelog) in ./changelog.d
|
||||
- [ ] Pull request includes a [sign off](https://github.com/matrix-org/matrix-ios-sdk/blob/develop/CONTRIBUTING.md#sign-off)
|
||||
- [ ] I read the [contributing guide](https://github.com/element-hq/element-ios/blob/develop/CONTRIBUTING.md).
|
||||
- [ ] Pull request contains a [changelog label](https://github.com/element-hq/element-x-ios/blob/develop/CONTRIBUTING.md#changelog).
|
||||
- [ ] Pull request includes a [sign off](https://github.com/matrix-org/matrix-ios-sdk/blob/develop/CONTRIBUTING.md#sign-off).
|
||||
|
||||
**UI changes have been tested with:**
|
||||
- [ ] iPhone and iPad simulators in portrait and landscape orientations.
|
||||
|
31
.github/release.yml
vendored
Normal file
31
.github/release.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
changelog:
|
||||
categories:
|
||||
- title: ✨ Features
|
||||
labels:
|
||||
- pr-feature
|
||||
- title: 🙌 Improvements
|
||||
labels:
|
||||
- pr-change
|
||||
- title: 🐛 Bugfixes
|
||||
labels:
|
||||
- pr-bugfix
|
||||
- title: ⚠️ API Changes
|
||||
labels:
|
||||
- pr-api
|
||||
- title: 🗣 Translations
|
||||
labels:
|
||||
- pr-i18n
|
||||
- title: 🧱 Build
|
||||
labels:
|
||||
- pr-build
|
||||
- title: 📄 Documentation
|
||||
labels:
|
||||
- pr-doc
|
||||
- title: 🚧 In development 🚧
|
||||
labels:
|
||||
- pr-wip
|
||||
|
||||
- title: Others
|
||||
labels:
|
||||
- pr-misc
|
||||
- "*"
|
@ -99,55 +99,7 @@ New screen flows are currently using the MVVM-Coordinator pattern. Please refer
|
||||
|
||||
## Changelog
|
||||
|
||||
All changes, even minor ones, need a corresponding changelog / newsfragment
|
||||
entry. These are managed by [Towncrier](https://github.com/twisted/towncrier).
|
||||
|
||||
To create a changelog entry, make a new file in the `changelog.d` directory
|
||||
named in the format of `ElementXiOSIssueNumber.type`. The type can be one of the
|
||||
following:
|
||||
|
||||
- `feature` for a new feature
|
||||
- `change` for updates to an existing feature
|
||||
- `bugfix` for bug fix
|
||||
- `api` for an api break
|
||||
- `i18n` for translations
|
||||
- `build` for changes related to build, tools, CI/CD
|
||||
- `doc` for updates to the documentation
|
||||
- `wip` for anything that isn't ready to ship and will be enabled at a later date
|
||||
- `misc` for other changes
|
||||
|
||||
This file will become part of our [changelog](CHANGES.md) at the next
|
||||
release, so the content of the file should be a short description of your
|
||||
change in the same style as the rest of the changelog. The file must only
|
||||
contain one line. It can contain Markdown formatting. It should start with the
|
||||
area of the change (screen, module, ...) and end with a full stop (.) or an
|
||||
exclamation mark (!) for consistency.
|
||||
|
||||
Adding credits to the changelog is encouraged, we value your
|
||||
contributions and would like to have you shouted out in the release notes!
|
||||
|
||||
For example, a fix for an issue #1234 would have its changelog entry in
|
||||
`changelog.d/1234.bugfix`, and contain content like:
|
||||
|
||||
> Voice Messages: Fix a crash when sending a voice message. Contributed by
|
||||
> Jane Matrix.
|
||||
|
||||
If there are multiple pull requests involved in a single bugfix/feature/etc,
|
||||
then the content for each `changelog.d` file should be the same. Towncrier will
|
||||
merge the matching files together into a single changelog entry when we come to
|
||||
release.
|
||||
|
||||
There are exceptions on the `ElementXiOSIssueNumber.type` entry format. Even if
|
||||
it is not encouraged, you can use:
|
||||
|
||||
- `pr-[PRNumber].type` for a PR with no related issue
|
||||
- `x-nolink-[AnyNumber].type` for a PR with a change entry that will not have a link automatically appended. It must be used for internal project update only. `AnyNumber` should be a value that does not clash with existing files.
|
||||
|
||||
To preview the changelog for pending changelog entries, use:
|
||||
|
||||
```bash
|
||||
$ towncrier build --draft --version 1.2.3
|
||||
```
|
||||
Our [changelog](CHANGES.md) is automatically generated by GitHub, based on the PR title that you use when opening the issue. The changelog can be categorised by applying on of the [`pr-` labels](https://github.com/element-hq/element-x-ios/labels?q=pr-) to your PR. The mapping of Label → Section can be found in the [release.yml](.github/release.yml) file. The contribution will be automatically credited to your GitHub username.
|
||||
|
||||
## Coding style
|
||||
|
||||
|
@ -5,6 +5,9 @@ SwiftLint.lint(inline: true)
|
||||
|
||||
let danger = Danger()
|
||||
|
||||
// All of the new and modified files together.
|
||||
let editedFiles = danger.git.modifiedFiles + danger.git.createdFiles
|
||||
|
||||
// Warn when there is a big PR
|
||||
if (danger.github.pullRequest.additions ?? 0) > 1000 {
|
||||
warn("This pull request seems relatively large. Please consider splitting it into multiple smaller ones.")
|
||||
@ -15,14 +18,6 @@ if danger.github.pullRequest.body?.isEmpty ?? true {
|
||||
warn("Please provide a description for this PR.")
|
||||
}
|
||||
|
||||
// Request a changelog for each app change
|
||||
let editedFiles = danger.git.modifiedFiles + danger.git.createdFiles
|
||||
let changelogFiles = editedFiles.filter { $0.hasPrefix("changelog.d/") }
|
||||
|
||||
if editedFiles.count > 0, changelogFiles.isEmpty {
|
||||
warn("Please add a changelog.")
|
||||
}
|
||||
|
||||
// Check for a ticket number
|
||||
if let ticketNumberRegex = try? NSRegularExpression(pattern: "#\\d+") {
|
||||
let missingTicketNumber = !danger.git.commits.filter {
|
||||
@ -84,3 +79,11 @@ let hasPngs = !editedFiles.filter { $0.lowercased().contains(".xcassets") && $0.
|
||||
if hasPngs {
|
||||
warn("You seem to have made changes to some resource images. Please consider using an SVG or PDF.")
|
||||
}
|
||||
|
||||
if danger.github.pullRequest.title.hasSuffix("…") {
|
||||
fail("Please provide a complete title that can be used as a changelog entry.")
|
||||
}
|
||||
|
||||
if danger.github.issue.labels.filter({ $0.name.hasPrefix("pr-") }).count != 1 {
|
||||
fail("Please add a `pr-` label to categorise the changelog entry.")
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
{# iOS Repositories #}
|
||||
{%- set gh_sdk = "https://github.com/matrix-org/matrix-rust-sdk" -%}
|
||||
{%- set gh_element = "https://github.com/element-hq/element-x-ios" -%}
|
||||
|
||||
## {{ versiondata.name }} {{ versiondata.version }} ({{ versiondata.date }})
|
||||
{% for section, _ in sections.items() %}
|
||||
|
||||
{% if sections[section] %}
|
||||
{% for category, val in definitions.items() if category in sections[section]%}
|
||||
{{ definitions[category]['name'] }}
|
||||
|
||||
{% if definitions[category]['showcontent'] %}
|
||||
{% for text, values in sections[section][category].items() %}
|
||||
{# Build all types of links we can have from our different repositories #}
|
||||
{%- set links = [] -%}
|
||||
{%- for value in values %}
|
||||
{%- if value.startswith("sdk-") %}
|
||||
{%- set gh_issue = value.replace("sdk-", "") -%}
|
||||
{{- links.append( "[#%s](%s/issues/%s)" | format(gh_issue, gh_sdk, gh_issue) ) | default("", True) -}}
|
||||
{%- elif value.startswith("#") %}
|
||||
{%- set gh_issue = value.replace("#", "") -%}
|
||||
{{- links.append( "[#%s](%s/issues/%s)" | format(gh_issue, gh_element, gh_issue) ) | default("", True) -}}
|
||||
{%- elif value.startswith("pr-") %}
|
||||
{%- set pr = value.replace("pr-", "") -%}
|
||||
{{- links.append( "[#%s](%s/pull/%s)" | format(pr, gh_element, pr) ) | default("", True) -}}
|
||||
{%- elif value.startswith("x-nolink-") %}
|
||||
{{- nil | default("", True) -}}
|
||||
{% else %}
|
||||
{{- links.append(value) | default("", True) -}}
|
||||
{% endif -%}
|
||||
{% endfor -%}
|
||||
{% if links|length == 0 %}
|
||||
- {{ text }}
|
||||
{% else %}
|
||||
- {{ text }} ({{ links | join(', ') }})
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
- {{ sections[section][category]['']|join(', ') }}
|
||||
|
||||
{% endif %}
|
||||
{% if sections[section][category]|length == 0 %}
|
||||
No significant changes.
|
||||
|
||||
{% else %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
No significant changes.
|
||||
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
@ -38,10 +38,6 @@ install_xcode_cloud_brew_dependencies () {
|
||||
fi
|
||||
}
|
||||
|
||||
install_xcode_cloud_python_dependencies () {
|
||||
pip3 install towncrier # Install towncrier for generating changelogs
|
||||
}
|
||||
|
||||
setup_github_actions_environment() {
|
||||
unset HOMEBREW_NO_INSTALL_FROM_API
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
|
@ -11,8 +11,6 @@ bundle exec fastlane upload_dsyms_to_sentry dsym_path:"$CI_ARCHIVE_PATH/dSYMs"
|
||||
generate_what_to_test_notes
|
||||
|
||||
if [ "$CI_WORKFLOW" = "Release" ]; then
|
||||
install_xcode_cloud_python_dependencies
|
||||
|
||||
bundle exec fastlane release_to_github
|
||||
bundle exec fastlane prepare_next_release
|
||||
elif [ "$CI_WORKFLOW" = "Nightly" ]; then
|
||||
|
@ -1,6 +1,5 @@
|
||||
require 'yaml'
|
||||
require 'semantic'
|
||||
require_relative 'changelog'
|
||||
|
||||
before_all do
|
||||
xcversion(version: "15.2")
|
||||
@ -208,35 +207,30 @@ lane :release_to_github do
|
||||
api_token = ENV["GITHUB_TOKEN"]
|
||||
UI.user_error!("Invalid GitHub API token.") unless !api_token.to_s.empty?
|
||||
|
||||
# Get the Diawi link from Diawi action shared value
|
||||
diawi_link = lane_context[SharedValues::UPLOADED_FILE_LINK_TO_DIAWI]
|
||||
|
||||
release_version = get_version_number(target: "ElementX")
|
||||
|
||||
changes = export_version_changes(version: release_version)
|
||||
|
||||
description = ""
|
||||
if diawi_link.nil?
|
||||
description = "#{changes}"
|
||||
else
|
||||
# Generate the Diawi QR code file link
|
||||
diawi_app_id = URI(diawi_link).path.split('/').last
|
||||
diawi_qr_code_link = "https://www.diawi.com/qrcode/link/#{diawi_app_id}"
|
||||
|
||||
"[iOS AdHoc Release - Diawi Link](#{diawi_link})
|
||||

|
||||
#{changes}"
|
||||
end
|
||||
|
||||
github_release = set_github_release(
|
||||
repository_name: "element-hq/element-x-ios",
|
||||
api_token: api_token,
|
||||
name: release_version,
|
||||
tag_name: release_version,
|
||||
is_generate_release_notes: false,
|
||||
description: description
|
||||
is_generate_release_notes: true,
|
||||
)
|
||||
|
||||
release_date = Date.today.strftime("%Y-%m-%d")
|
||||
generated_notes = github_release["body"].gsub(/<!-- .*? -->/, '').gsub("### ", "\n").gsub("## ", "### ")
|
||||
UI.user_error!("The generated release notes are missing!") unless !generated_notes.to_s.empty?
|
||||
|
||||
# Prepend the new release notes to the CHANGES.md file
|
||||
changes_file = "../CHANGES.md"
|
||||
File.open(changes_file, "r+") do |file|
|
||||
content = file.read
|
||||
file.rewind
|
||||
file.write("## Changes in #{release_version} (#{release_date})#{generated_notes}\n\n#{content}")
|
||||
end
|
||||
|
||||
# The changelog will be committed when prepare_next_release is called.
|
||||
sh("git add #{changes_file}")
|
||||
end
|
||||
|
||||
lane :prepare_next_release do
|
||||
@ -366,13 +360,6 @@ private_lane :bump_build_number do
|
||||
increment_build_number(build_number: build_number)
|
||||
end
|
||||
|
||||
private_lane :export_version_changes do |options|
|
||||
Dir.chdir("..") do
|
||||
Changelog.update_topmost_section(version: options[:version], additional_entries: {})
|
||||
Changelog.extract_first_section
|
||||
end
|
||||
end
|
||||
|
||||
private_lane :update_app_icon do |options|
|
||||
caption_text = options[:caption_text]
|
||||
UI.user_error!("Invalid caption text.") unless !caption_text.to_s.empty?
|
||||
|
@ -1,75 +0,0 @@
|
||||
#
|
||||
# Copyright 2020 New Vector Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "tempfile"
|
||||
require "fileutils"
|
||||
require "date"
|
||||
|
||||
# Helper methods to handle updates of the Changelog file
|
||||
#
|
||||
module Changelog
|
||||
CHANGES_SEPARATOR_REGEX = /^\#\#\ Changes/.freeze
|
||||
FILE = "CHANGES.md"
|
||||
|
||||
# Update the topmost section of the changelog to put version+date in title + add entry for dependency updates
|
||||
#
|
||||
# @param [String] version The version that we are releasing to use in the new title of the first section
|
||||
# @param [Hash<String, Array<String>>] additional_entries
|
||||
# List of lines/entries to add under the each subsection of the first section
|
||||
# The keys of the hash are the name of the subsections, without trailing`:`, e.g. "Improvements".
|
||||
# The values are the list of lines to add to that subsection
|
||||
# (the ` * ` bullet point will be added automatically for each line)
|
||||
#
|
||||
def self.update_topmost_section(version:, additional_entries:)
|
||||
|
||||
# Create temporary towncrier changelog entries for additional entries
|
||||
# Use a low index to make them appear first
|
||||
# Those additional entries are basically dependency updates
|
||||
entry_count = 0
|
||||
additional_entries.each do |subsection, entries|
|
||||
entries.each do |entry|
|
||||
file = "changelog.d/x-nolink-#{entry_count}.#{subsection}"
|
||||
File.write(file, "#{entry}")
|
||||
Git.add!(files: file)
|
||||
Git.commit!(message: "changelog.d: #{entry}", add_all: true)
|
||||
entry_count += 1
|
||||
end
|
||||
end
|
||||
|
||||
# Let towncrier update the change
|
||||
system("towncrier", "build", "--version", "#{version}", "--yes")
|
||||
end
|
||||
|
||||
# Returns the first section of the Changelog, corresponding to the changes in the latest version
|
||||
#
|
||||
def self.extract_first_section
|
||||
lines = []
|
||||
File.open(FILE, "r") do |file|
|
||||
section_index = 0
|
||||
file.each_line do |line|
|
||||
is_separator_line = (line.chomp =~ CHANGES_SEPARATOR_REGEX)
|
||||
section_index += 1 if is_separator_line
|
||||
break if section_index >= 2
|
||||
|
||||
lines.append(line) if section_index == 1
|
||||
end
|
||||
end
|
||||
lines[0..-2].join # Remove last line (title of section 2)
|
||||
end
|
||||
|
||||
end
|
@ -1,50 +0,0 @@
|
||||
[tool.towncrier]
|
||||
name = "Changes in"
|
||||
filename = "CHANGES.md"
|
||||
directory = "changelog.d"
|
||||
template = "changelog.d/_template.md.jinja"
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "feature"
|
||||
name = "✨ Features"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "change"
|
||||
name = "🙌 Improvements"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "bugfix"
|
||||
name = "🐛 Bugfixes"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "api"
|
||||
name = "⚠️ API Changes"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "i18n"
|
||||
name = "🗣 Translations"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "build"
|
||||
name = "🧱 Build"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "doc"
|
||||
name = "📄 Documentation"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "wip"
|
||||
name = "🚧 In development 🚧"
|
||||
showcontent = true
|
||||
|
||||
[[tool.towncrier.type]]
|
||||
directory = "misc"
|
||||
name = "Others"
|
||||
showcontent = true
|
Loading…
x
Reference in New Issue
Block a user