Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/commands/release.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: Cut a new rss2msg release — derive the version, commit the changelog to main, then tag and push to trigger the release pipeline.
description: Cut a new rss2msg release — derive the version, roll the BUSL Change Date, commit the changelog to main, then tag and push to trigger the release pipeline.
argument-hint: "[version] e.g. v1.0.0 (optional; derived from commits if omitted)"
---

Expand All @@ -11,5 +11,5 @@ derive it from the commit history with `git cliff --bumped-version`):
$ARGUMENTS

Invoke the `cut-release` skill and follow it exactly. Run on `main` (not a worktree),
stage only `CHANGELOG.md`, and **confirm with me before pushing the tag** — that push
stage only `CHANGELOG.md` and `LICENSE`, and **confirm with me before pushing the tag** — that push
triggers the public release pipeline.
53 changes: 37 additions & 16 deletions .claude/skills/cut-release/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: cut-release
description: Use when cutting a new rss2msg release / version — derives the next semver from Conventional Commits with git-cliff, commits the regenerated CHANGELOG.md to main, then tags and pushes to trigger the GoReleaser pipeline. Triggers on "cut a release", "new version", "release vX.Y.Z", "/release".
description: Use when cutting a new rss2msg release / version — derives the next semver from Conventional Commits with git-cliff, rolls the BUSL Change Date in LICENSE, commits both to main, then tags and pushes to trigger the GoReleaser pipeline. Triggers on "cut a release", "new version", "release vX.Y.Z", "/release".
---

# Cutting a new rss2msg release
Expand All @@ -10,10 +10,12 @@ rss2msg ships through a **tag-driven** pipeline: pushing a `vX.Y.Z` tag triggers
multi-platform binaries, Linux packages, a multi-arch Docker image, the Homebrew cask,
and the GitHub Release. The version comes entirely from the pushed tag.

This skill owns the changelog locally: it regenerates and **commits `CHANGELOG.md` to
`main` before tagging**, so the tagged commit already carries the populated changelog
that GoReleaser bundles into the artifacts. The workflow does **not** regenerate or sync
the changelog — that is this skill's job.
This skill owns two per-release files locally: it regenerates and **commits
`CHANGELOG.md` to `main` before tagging**, so the tagged commit already carries the
populated changelog that GoReleaser bundles into the artifacts, and it **rolls the BUSL
`Change Date` in `LICENSE`** so each version converts to Apache-2.0 four years after its
own release. The workflow does **not** regenerate or sync either file — that is this
skill's job.

See [docs/development/releasing.md](../../../docs/development/releasing.md) for the full
pipeline reference.
Expand All @@ -32,12 +34,12 @@ copy.
## Hard rules

- **Never `git add -A` / `git add .`** — this repo is an Obsidian vault with
auto-staging. Stage **only** `CHANGELOG.md` with an explicit pathspec.
auto-staging. Stage **only** `CHANGELOG.md` and `LICENSE` with explicit pathspecs.
- **Never** `--no-verify` or bypass hooks.
- **Confirm with the user before pushing the tag** — that push triggers the public
release. Pushing the changelog commit to `main` happens first and does not trigger the
release (only a tag push does).
- **Never put `[skip ci]` in the changelog commit message.** Step 5 tags that exact
- **Never put `[skip ci]` in the changelog commit message.** Step 6 tags that exact
commit, and GitHub honors `[skip ci]` on a tag push's HEAD commit — so a `[skip ci]`
changelog commit silently **skips the release workflow**. (This bit v0.3.0.)
- **Abort** on any failed preflight check and report exactly what failed; do not paper over it.
Expand Down Expand Up @@ -92,28 +94,47 @@ Get explicit go-ahead on the version before changing any files. If the commits s
last tag are thin or unconventional (git-cliff skips non-Conventional and merge commits),
point that out.

### 4. Regenerate and commit CHANGELOG.md to main
### 4. Roll the BUSL Change Date in LICENSE

Regenerate the full changelog with the new tag label, then stage **only** that file:
rss2msg ships under the Business Source License 1.1, and the Change Date is a
**per-version** value — BUSL applies "separately for each version". Each release must
carry a Change Date four years out (the BUSL ceiling), or that version's
source-available window silently shrinks.

```bash
sed -i "s/^Change Date:.*/Change Date: $(date -u -d '+4 years' +%Y-%m-%d)/" LICENSE
grep '^Change Date:' LICENSE # verify: four years from today, YYYY-MM-DD
git diff --stat LICENSE # verify: exactly one line changed
```

- Change **only** the `Change Date:` line. If `git diff` shows anything else touched,
revert and stop — the rest of `LICENSE` is legal text and is never edited by this skill.
- The value is always today + 4 years. Do not carry the previous release's date forward,
and do not invent a different horizon.

### 5. Regenerate and commit CHANGELOG.md to main

Regenerate the full changelog with the new tag label, then stage **only** the changelog
and the license bump from step 4:

```bash
git cliff --config cliff.toml --tag "<version>" --output CHANGELOG.md
git add CHANGELOG.md # explicit pathspec — nothing else
git status # verify ONLY CHANGELOG.md is staged
git add CHANGELOG.md LICENSE # explicit pathspecs — nothing else
git status # verify ONLY these two files are staged
git commit -m "chore(release): update CHANGELOG.md for <version>"
git push origin main
```

Notes:
- The `chore(release):` prefix matters: `cliff.toml` skips `^chore\(release\):` commits,
so this commit never pollutes a future changelog.
- **Do not append `[skip ci]`.** Step 5 tags this same commit, and GitHub skips the
- **Do not append `[skip ci]`.** Step 6 tags this same commit, and GitHub skips the
tag-triggered release workflow when its HEAD commit message contains `[skip ci]` — which
is exactly how the v0.3.0 release got silently skipped. The cost of omitting it is one
redundant CI run on `main`, which is acceptable; a skipped release is not.
- Verify the staged set is **only** `CHANGELOG.md` before committing (auto-staging hazard).
- Verify the staged set is **only** `CHANGELOG.md` and `LICENSE` before committing (auto-staging hazard).

### 5. Tag, confirm, and push
### 6. Tag, confirm, and push

```bash
git tag "<version>" # tags the changelog commit you just pushed
Expand All @@ -126,7 +147,7 @@ release. On confirmation:
git push origin "<version>"
```

### 6. Report
### 7. Report

Print the link to the running release workflow so the user can watch it:

Expand All @@ -143,7 +164,7 @@ Homebrew cask for non-prerelease tags, and the GitHub Release).
- **Prerelease tags** (`-rc.1`, etc.): valid and supported. GoReleaser skips the Homebrew
cask for prereleases automatically (`skip_upload: auto`).
- **`v0.0.*` tags** are ignored by git-cliff (`skip_tags`), so don't use them.
- If the `git push origin main` in step 4 is rejected because `main` is branch-protected
- If the `git push origin main` in step 5 is rejected because `main` is branch-protected
against direct pushes, stop — the changelog must reach `main` before the tag. Surface
this to the maintainer rather than forcing it.
- **Release skipped (no Release run after the tag push)?** The usual cause is `[skip ci]`
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/cla.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Asks first-time contributors to sign the CLA (CLA.md) before their PR can be merged,
# and records signatures in the `cla-signatures` branch of this repository.
#
# Setup required once, by a maintainer, before this workflow can pass:
# 1. Create a classic PAT with `repo` scope (or a fine-grained PAT with Contents:
# read/write on this repository) and add it as the `CLA_SIGNATURES_TOKEN` secret.
# The action needs it to commit the signature file; the default GITHUB_TOKEN is not
# enough because the write happens outside the PR's ref.
# 2. Add a branch-protection / ruleset requirement on `main` for the "CLA Assistant"
# status check, so an unsigned PR cannot be merged.
#
# `pull_request_target` is required so the workflow can comment and set a status on pull
# requests from forks. This job never checks out or executes PR code — it only reads the
# event payload and comment text — so the usual pull_request_target hazard does not apply.
name: CLA

on:
issue_comment:
types: [created]
pull_request_target:
types: [opened, closed, synchronize]

permissions:
actions: write
contents: write
pull-requests: write
statuses: write

jobs:
cla:
name: CLA Assistant
runs-on: ubuntu-latest
steps:
- name: Check or record CLA signature
if: >-
github.event_name == 'pull_request_target' ||
github.event.comment.body == 'recheck' ||
github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA'
uses: contributor-assistant/github-action@v2.6.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_SIGNATURES_TOKEN }}
with:
path-to-document: https://github.com/IAmBod/rss2msg/blob/main/CLA.md
path-to-signatures: signatures/version1/cla.json
branch: cla-signatures
# Maintainer and bots never need to sign.
allowlist: IAmBod,dependabot[bot],github-actions[bot]
custom-notsigned-prcomment: >-
Thanks for the pull request! Before it can be merged, please read the
[Contributor License Agreement](https://github.com/IAmBod/rss2msg/blob/main/CLA.md)
and sign it by posting the comment below. rss2msg is source-available under the
Business Source License 1.1, and the CLA is what lets the project offer your
contribution under those terms — you keep your copyright.
custom-allsigned-prcomment: >-
All contributors have signed the CLA. Thank you!
2 changes: 1 addition & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ nfpms:
package_name: rss2msg
vendor: IAmBod
homepage: https://github.com/IAmBod/rss2msg
maintainer: Bödei Károly <info@randombullsh.it>
maintainer: Bödei Károly <info@iambod.dev>
license: BUSL-1.1
description: |-
RSS/Atom/JSON feed-to-message bridge.
Expand Down
118 changes: 118 additions & 0 deletions CLA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# rss2msg Contributor License Agreement

Thank you for your interest in contributing to rss2msg (the "Project"), maintained by
Bödei Károly (the "Maintainer").

This Contributor License Agreement ("Agreement") documents the rights you grant to the
Maintainer when you contribute. It is adapted from the Apache Software Foundation
Individual Contributor License Agreement v2.0.

**Why this exists.** rss2msg is distributed under the
[Business Source License 1.1](LICENSE) — a source-available license under which the
Maintainer also offers separate commercial licenses. For the Project to be offered under
those terms, and for each version to convert to the Apache License 2.0 on its Change
Date, the Maintainer needs a clear written grant of rights covering every contribution.
Without one, contributed code could only ever be offered under the exact terms it
arrived under.

**You keep your copyright.** This Agreement is a license, not a transfer of ownership.

## 1. Definitions

**"You"** means the individual or legal entity agreeing to this Agreement.

**"Contribution"** means any original work of authorship, including any modifications or
additions to an existing work, that is intentionally submitted by You to the Maintainer
for inclusion in, or documentation of, the Project. "Submitted" means any form of
electronic, verbal, or written communication sent to the Maintainer or its
representatives — including pull requests, issues, and electronic mailing lists — but
excluding any communication conspicuously marked or otherwise designated in writing by
You as "Not a Contribution".

## 2. Grant of copyright license

Subject to the terms of this Agreement, You grant to the Maintainer and to recipients of
software distributed by the Maintainer a perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to reproduce, prepare derivative works of,
publicly display, publicly perform, sublicense, and distribute Your Contributions and
such derivative works.

## 3. Grant of patent license

Subject to the terms of this Agreement, You grant to the Maintainer and to recipients of
software distributed by the Maintainer a perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Project. This license
applies only to those patent claims licensable by You that are necessarily infringed by
Your Contribution alone, or by combination of Your Contribution with the Project.

If any entity institutes patent litigation against You or any other entity alleging that
Your Contribution, or the Project to which You contributed, constitutes direct or
contributory patent infringement, then any patent licenses granted to that entity under
this Agreement for that Contribution or Project terminate as of the date such litigation
is filed.

## 4. Outbound licensing

You acknowledge and agree that the Maintainer may license the Project, including Your
Contributions, under any terms the Maintainer chooses. This expressly includes:

- the Business Source License 1.1, and any successor source-available license;
- the Apache License 2.0, to which each version converts on its Change Date;
- separate commercial or proprietary licenses, including licenses permitting the
operation of a hosted or managed service based on the Project.

The Maintainer is under no obligation to include Your Contribution in the Project or in
any distribution of it.

## 5. Your representations

You represent that:

1. You are legally entitled to grant the licenses above.
2. Each of Your Contributions is Your original creation, or You otherwise have the right
to submit it under this Agreement.
3. If your employer has rights to intellectual property that You create, You have
received permission to make Contributions on behalf of that employer, your employer
has waived such rights, or your employer has executed a separate Corporate CLA with
the Maintainer.

If You wish to submit work that is not Your original creation, submit it separately from
any Contribution, identifying the complete details of its source and of any license or
other restriction you are personally aware of, and conspicuously mark the work as
"Submitted on behalf of a third party: [named here]".

## 6. No warranty, no support obligation

You are not expected to provide support for Your Contributions, except to the extent You
wish to. Unless required by applicable law or agreed to in writing, You provide Your
Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied, including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.

## 7. Notification

You agree to notify the Maintainer of any facts or circumstances you become aware of that
would make these representations inaccurate in any respect.

## How to sign

Signing is automated — there is nothing to print, scan, or email.

When you open your first pull request, a bot comments with a link to this document. Reply
on that pull request with exactly:

```
I have read the CLA Document and I hereby sign the CLA
```

Your signature is recorded against your GitHub username in the `cla-signatures` branch of
this repository. You will not be asked again on later pull requests.

**Contributing on behalf of a company?** Email <info@iambod.dev> for a Corporate CLA
before submitting.

## Related

- [LICENSE](LICENSE) — the Business Source License 1.1 terms the Project ships under.
- [CONTRIBUTING.md](CONTRIBUTING.md) — how to get a change reviewed and merged.
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ representative at an online or offline event.

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
**info@randombullsh.it**.
**info@iambod.dev**.

All complaints will be reviewed and investigated promptly and fairly.

Expand Down
26 changes: 23 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ places:
or a coordinator backend (requires Docker), and
`bash scripts/check-doc-links.sh` if you touched `docs/` or the `README`.
5. **Open a pull request** against `main` and fill in the template.
6. **Sign the CLA** — a bot asks on your first PR; see [below](#contributor-license-agreement).

## Code of Conduct

Expand All @@ -45,6 +46,25 @@ Please do **not** open public issues for security vulnerabilities — see

## License

rss2msg is distributed under the [Business Source License 1.1](LICENSE). By
contributing, you agree that your contributions are licensed under the same terms
as the rest of the project.
rss2msg is **source-available**, not open source: it is distributed under the
[Business Source License 1.1](LICENSE). You may use, modify, and redistribute it,
including commercially — the one carve-out is offering rss2msg to third parties as a
hosted or managed "Feed-to-Message Service", which needs a separate commercial license.
Each version converts to the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
on its Change Date. See [`LICENSE`](LICENSE) for the exact terms.

## Contributor License Agreement

Before your first pull request can be merged, you need to sign the
[Contributor License Agreement](CLA.md). It is adapted from the Apache Software
Foundation's Individual CLA.

**You keep your copyright** — the CLA is a license grant, not a transfer. What it adds
is permission for the project to offer your contribution under the terms above,
including the separate commercial licenses and the eventual Apache-2.0 conversion.
Without it, contributed code could only be offered under the exact terms it arrived
under, which would fracture the licensing of the codebase.

Signing is automated: open a PR, and a bot comments with a link to the document and the
one-line comment to reply with. You are only asked once. Contributing on behalf of a
company? Email <info@iambod.dev> for a Corporate CLA first.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Change Date: 2030-06-01
Change License: Apache License, Version 2.0

For information about alternative licensing arrangements for the Licensed Work,
please contact info@randombullsh.it.
please contact info@iambod.dev.

-----------------------------------------------------------------------------

Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,24 @@ Full documentation lives in [`docs/`](./docs/index.md). Start there, or jump in:

---

## Contributing

Contributions are welcome — see [CONTRIBUTING.md](./CONTRIBUTING.md) for the workflow
and [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) for the ground rules. Please report
security issues privately per [SECURITY.md](./SECURITY.md) rather than as public issues.

Before a first pull request is merged, contributors sign the
[Contributor License Agreement](./CLA.md) — a bot handles it, and you keep your
copyright.

## License

rss2msg is licensed under the [Business Source License 1.1](./LICENSE).
rss2msg is **source-available**, not open source. It is distributed under the
[Business Source License 1.1](./LICENSE).

You may use, modify, and redistribute it freely, **including for commercial
purposes** — the one exception is that you may not offer rss2msg to third parties
as a hosted or managed "Feed-to-Message Service" without a separate commercial
license. Each released version converts to the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
on its Change Date (four years after release). See [`LICENSE`](./LICENSE) for the
exact terms; for commercial-licensing questions, contact info@randombullsh.it.
on its Change Date, four years after that version is released. See [`LICENSE`](./LICENSE)
for the exact terms; for commercial-licensing questions, contact info@iambod.dev.
Loading
Loading