mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-07-15 07:28:55 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5f1b68c8de | |||
| 72b605710e | |||
| 0ac0bd93ae | |||
| fe9f718c6e | |||
| e333f5a8e5 |
@@ -0,0 +1 @@
|
||||
Fixed `global.oauth.compatibility_mode` being required, despite being ignored, when the `[global.oauth.oidc]` config section is provided.
|
||||
+30
-25
@@ -1,27 +1,32 @@
|
||||
[
|
||||
{
|
||||
"type": "file",
|
||||
"name": "index",
|
||||
"label": "Development Guide"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "contributing",
|
||||
"label": "Contributing"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "code_style",
|
||||
"label": "Code Style Guide"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "testing",
|
||||
"label": "Testing"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "hot_reload",
|
||||
"label": "Hot Reloading"
|
||||
}
|
||||
{
|
||||
"type": "file",
|
||||
"name": "index",
|
||||
"label": "Development Guide"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "contributing",
|
||||
"label": "Contributing"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "code_style",
|
||||
"label": "Code Style Guide"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "testing",
|
||||
"label": "Testing"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "hot_reload",
|
||||
"label": "Hot Reloading"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "releasing",
|
||||
"label": "Releasing"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# Releasing
|
||||
|
||||
Continuwuity is rapidly evolving software that needs to keep up with an ecosystem that demands equally faced paced
|
||||
development. While we generally encourage people follow the `main` branch, not everyone has the time or will to keep up
|
||||
with even nightly updates. For this reason, we do regular releases.
|
||||
|
||||
In order to ensure that releases are stable and predictable, the process defined in this document should be followed.
|
||||
|
||||
## Schedule
|
||||
|
||||
The release `YY.MM` should be forked from the `main` branch on the first day of the final week of the month.
|
||||
Immediately after, `YY.MM.0-rc.1` should be tagged and released as a pre-release.
|
||||
|
||||
Then, for each day of the final week of the month, if there have been bug fixes since the last release candidate, a new
|
||||
release candidate should be tagged and released as a pre-release. This means there can be between 1 and 6
|
||||
release candidates for a given release.
|
||||
|
||||
On the last day of the final week of the month, if there are no outstanding serious bugs, the full release should be
|
||||
tagged and released.
|
||||
|
||||
If there ARE serious bugs found at the time the final release is due, the release should be delayed until the
|
||||
bugs are fixed. Additionally, another release candidate should be tagged for at least 24 hours after the patch is
|
||||
released, to allow for testing and verification of the fix. Only then can the final release be made.
|
||||
|
||||
This means a release timeline MIGHT look like:
|
||||
|
||||
- Week 1: Bugfixes from the previous release that missed the cycle
|
||||
- Week 2: New major features & other changes
|
||||
- Week 3: New minor features & bugfixing
|
||||
- Week 4: Release candidates and final release
|
||||
- Day 1: Fork release branch from `main` and tag `YY.MM.0-rc.1`
|
||||
- Day 2: If there are bugfixes, tag `YY.MM.0-rc.2`
|
||||
- Day 3: If there are bugfixes, tag `YY.MM.0-rc.3`
|
||||
- Day 4: If there are bugfixes, tag `YY.MM.0-rc.4`
|
||||
- Day 5: If there are bugfixes, tag `YY.MM.0-rc.5`
|
||||
- Day 6: If there are bugfixes, tag `YY.MM.0-rc.6`
|
||||
- Day 7: If there are no serious bugs, tag `YY.MM.0` and release.
|
||||
|
||||
New changes of any sort may be made to the `main` branch at any point during the month, but they will not be included
|
||||
in the release until the next cycle.
|
||||
|
||||
### Off-schedule releases (patches)
|
||||
|
||||
Sometimes, critical bugs may be discovered that require an immediate release.
|
||||
In this case, a new branch should be forked **from the previous release tag**, incrementing the patch value (e.g. `YY.MM.0` ->` YY.MM.1`)
|
||||
This will ensure that the critical bug is fixed without introducing any new changes that may potentially be incompatible.
|
||||
|
||||
### Security releases
|
||||
|
||||
Following the [security policy](../security.mdx), security releases might be made off-cycle, and may even require
|
||||
creating new releases for older versions (backports). It is imperative that security patches are tested BEFORE being
|
||||
pushed to the public repository, as once the cat is out of the bag, it doesn't go back in. Consequently,
|
||||
there is no "pre-release" system for security releases - security patches always go straight to release.
|
||||
|
||||
Not all security fixes require a new release. If there are several low-severity security problems that are awaiting
|
||||
an upstream merge, they should instead wait for the next scheduled release, unless they are critical enough to warrant
|
||||
an immediate release.
|
||||
|
||||
Security patches should NEVER be pushed to the public repository when a release is not planned to be made very soon
|
||||
after. The shorter the window between the diff going live and the release, the smaller the window for exploit.
|
||||
|
||||
### Release candidates
|
||||
|
||||
Release candidates are the primary form of pre-release - they imply a feature freeze, which allows maintainers and
|
||||
contributors to focus on fixing bugs before the ultimate release, which ensures all new features are stable and working
|
||||
as intended. Simply relying on deployments to run main has proven to be insufficient for filling this role,
|
||||
so release candidates are a necessary step in the release process.
|
||||
|
||||
Release candidates should be announced in the same way any other release is (ping in the announcements room,
|
||||
announcement sent out via the checker, etc), but should be clearly marked as a pre-release. Extra attention to detail
|
||||
should be spent ensuring breaking changes are clearly communicated.
|
||||
|
||||
### Alphas and Betas
|
||||
|
||||
Alphas and betas may be created during any time of the month, and it is recommended to do so after merging a major
|
||||
feature, especially if the release candidate cycle is not close to starting. This is not expected to be commonplace, so
|
||||
announcing these releases is up to the discretion of the release manager.
|
||||
@@ -9,7 +9,7 @@
|
||||
"id": 15,
|
||||
"mention_room": true,
|
||||
"date": "2026-07-10",
|
||||
"message": "[Continuwuity 26.6.0](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v26.6.0) is finally out! This is by far our largest release yet, and it wouldn't have been possible without our community. Thank you so much for all of your patience, support, and/or development time over the last three months <3"
|
||||
"message": "[Continuwuity 26.6.1](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v26.6.1) has just been released! This release contains a bunch of bugfixes for bugs found initially after 26.6.0's release - please read the changelog before updating!"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1014,7 +1014,7 @@ pub(super) async fn resolve_true_destination(
|
||||
let resolver: &MatrixResolver = if no_cache {
|
||||
&MatrixResolverBuilder::new()
|
||||
.dangerous_tls_accept_invalid_certs(self.services.server.config.allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure)
|
||||
.http_client(self.services.client.default.clone())
|
||||
.http_client(self.services.client.dns.clone())
|
||||
.build()?
|
||||
} else {
|
||||
&self.services.client.matrix_resolver
|
||||
|
||||
@@ -54,7 +54,7 @@ pub(super) async fn fetch_support_well_known(&self, server_name: OwnedServerName
|
||||
let response = self
|
||||
.services
|
||||
.client
|
||||
.default
|
||||
.external_resource
|
||||
.get(format!("https://{server_name}/.well-known/matrix/support"))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
@@ -2442,6 +2442,7 @@ pub struct OauthConfig {
|
||||
/// legacy authentication will be unable to log in.
|
||||
///
|
||||
/// default: "hybrid"
|
||||
#[serde(default)]
|
||||
compatibility_mode: OAuthMode,
|
||||
|
||||
/// display: hidden
|
||||
|
||||
@@ -134,7 +134,7 @@ async fn check(&self) -> Result<()> {
|
||||
let response = self
|
||||
.services
|
||||
.client
|
||||
.default
|
||||
.external_resource
|
||||
.get(CHECK_FOR_ANNOUNCEMENTS_URL)
|
||||
.send()
|
||||
.await?
|
||||
|
||||
+14
-19
@@ -16,9 +16,9 @@ pub struct Service {
|
||||
pub matrix_resolver: Arc<MatrixResolver>,
|
||||
pub dns_resolver: Arc<TokioResolver>,
|
||||
|
||||
pub default: reqwest::Client,
|
||||
pub dns: reqwest::Client,
|
||||
pub url_preview: reqwest::Client,
|
||||
pub extern_media: reqwest::Client,
|
||||
pub external_resource: reqwest::Client,
|
||||
pub federation: reqwest::Client,
|
||||
pub federation_slow: reqwest::Client,
|
||||
pub sender: reqwest::Client,
|
||||
@@ -35,17 +35,17 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
|
||||
let dns_resolver = get_dns_resolver(args.server)?;
|
||||
|
||||
let dns_client = base(&args.server.config)?
|
||||
.connect_timeout(Duration::from_secs(args.server.config.well_known_conn_timeout))
|
||||
.read_timeout(Duration::from_secs(args.server.config.well_known_timeout))
|
||||
.timeout(Duration::from_secs(args.server.config.well_known_timeout))
|
||||
.pool_max_idle_per_host(0)
|
||||
.redirect(redirect::Policy::limited(4))
|
||||
.build()?;
|
||||
|
||||
let matrix_resolver = Arc::new(MatrixResolverBuilder::new()
|
||||
.dangerous_tls_accept_invalid_certs(args.server.config.allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure)
|
||||
.http_client(
|
||||
base(&args.server.config)?
|
||||
.connect_timeout(Duration::from_secs(args.server.config.well_known_conn_timeout))
|
||||
.read_timeout(Duration::from_secs(args.server.config.well_known_timeout))
|
||||
.timeout(Duration::from_secs(args.server.config.well_known_timeout))
|
||||
.pool_max_idle_per_host(0)
|
||||
.redirect(redirect::Policy::limited(4))
|
||||
.build()?
|
||||
)
|
||||
.http_client(dns_client.clone())
|
||||
.dns_resolver(dns_resolver.clone())
|
||||
.build()?);
|
||||
let matrix_dns_resolver = matrix_resolver.create_dns_resolver();
|
||||
@@ -69,23 +69,19 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
matrix_resolver,
|
||||
dns_resolver,
|
||||
|
||||
default: base(config)?
|
||||
.dns_resolver(matrix_dns_resolver.clone())
|
||||
.build()?,
|
||||
dns: dns_client,
|
||||
|
||||
url_preview: base(config)
|
||||
.and_then(|builder| {
|
||||
builder_interface(builder, url_preview_bind_iface.as_deref())
|
||||
})?
|
||||
.local_address(url_preview_bind_addr)
|
||||
.dns_resolver(matrix_dns_resolver.clone())
|
||||
.timeout(Duration::from_secs(config.url_preview_timeout))
|
||||
.redirect(redirect::Policy::limited(3))
|
||||
.user_agent(url_preview_user_agent)
|
||||
.build()?,
|
||||
|
||||
extern_media: base(config)?
|
||||
.dns_resolver(matrix_dns_resolver.clone())
|
||||
external_resource: base(config)?
|
||||
.redirect(redirect::Policy::limited(3))
|
||||
.build()?,
|
||||
|
||||
@@ -128,7 +124,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
.build()?,
|
||||
|
||||
appservice: base(config)?
|
||||
.dns_resolver(matrix_dns_resolver.clone())
|
||||
.dns_resolver(matrix_dns_resolver)
|
||||
.connect_timeout(Duration::from_secs(5))
|
||||
.read_timeout(Duration::from_secs(config.appservice_timeout))
|
||||
.timeout(Duration::from_secs(config.appservice_timeout))
|
||||
@@ -138,7 +134,6 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
.build()?,
|
||||
|
||||
pusher: base(config)?
|
||||
.dns_resolver(matrix_dns_resolver)
|
||||
.connect_timeout(Duration::from_secs(config.pusher_conn_timeout))
|
||||
.timeout(Duration::from_secs(config.pusher_timeout))
|
||||
.pool_max_idle_per_host(1)
|
||||
|
||||
@@ -260,7 +260,7 @@ async fn location_request(&self, location: &str) -> Result<FileMeta> {
|
||||
let response = self
|
||||
.services
|
||||
.client
|
||||
.extern_media
|
||||
.external_resource
|
||||
.get(location)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
Reference in New Issue
Block a user