Skip to content

Commit 8484024

Browse files
committed
Contributing guide
1 parent 92b2e52 commit 8484024

File tree

6 files changed

+203
-7
lines changed

6 files changed

+203
-7
lines changed

.github/workflows/dependency-submission.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ jobs:
2121
uses: actions/setup-java@v4
2222
with:
2323
distribution: 'temurin'
24-
java-version: 17
24+
java-version: 21
2525
- name: Generate and submit dependency graph
2626
uses: gradle/actions/dependency-submission@v5

.github/workflows/deployment.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@ on:
88
push:
99
branches: [ main ]
1010
workflow_dispatch:
11+
inputs:
12+
snapshot:
13+
description: 'Publish as snapshot'
14+
type: boolean
15+
default: false
1116

1217
jobs:
1318
deployment:
1419
name: Publish to Maven Central
1520
runs-on: ubuntu-latest
21+
permissions:
22+
contents: write
1623

1724
steps:
1825
- name: Checkout
@@ -35,9 +42,16 @@ jobs:
3542

3643
- name: Publish to Maven Central
3744
env:
38-
ORG_GRADLE_PROJECT_SNAPSHOT: ${{ github.event_name == 'push' }}
45+
ORG_GRADLE_PROJECT_SNAPSHOT: ${{ github.event_name == 'push' || inputs.snapshot }}
3946
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
4047
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
4148
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }}
4249
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_KEY_PW }}
4350
run: ./gradlew publishToMavenCentral
51+
52+
- name: Create Git Tag
53+
if: github.event_name == 'workflow_dispatch' && !inputs.snapshot
54+
run: |
55+
VERSION=$(grep 'const val VERSION' build-logic/src/main/kotlin/kjwt/Projects.kt | sed 's/.*"\(.*\)".*/\1/')
56+
git tag "v$VERSION"
57+
git push origin "v$VERSION"

CONTRIBUTING.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Contributing to a Touchlab Project
2+
3+
## License
4+
5+
By contributing you agree for your contribution to be licensed under the same license as the project which can be found
6+
in the LICENSE file.
7+
If no LICENSE file is present, all intellectual property rights for the project and contributions to the project are
8+
reserved by Touchlab.
9+
10+
## Opening an issue
11+
12+
Issues can be useful for reporting bugs and requesting features.
13+
If you simply have a question about the project or how to use it, please instead reach out in
14+
the [Kotlinlang touchlab-tools channel](https://kotlinlang.slack.com/archives/CTJB58X7X)
15+
16+
### Reporting a Bug
17+
18+
When reporting a problem with the project please provide as much detail as possible including:
19+
20+
- The version of the project used as well as other relevant versions (eg: Kotlin, Android, iOS)
21+
- What behavior was expected
22+
- Steps to reproduce
23+
24+
#### Sample Project
25+
26+
Sharing a simple sample project which reproduces the issue is **immensely** helpful.
27+
Issues are often caused by project specific configurations and uses which are not practical for us to derive from a bug
28+
report.
29+
A reproducing project is often the first thing we ask for on difficult bugs and going through the process will help you
30+
make a more informed bug report.
31+
32+
### Requesting an Enhancement
33+
34+
We get a lot of great feedback from the community about how they use our projects and what can make them better.
35+
If you'd like to suggest an improvement that is not fixing a defect, please label it as an Enhancement.
36+
Share as much info as you can about your use case and how you would expect the enhancement might work.
37+
Please understand that even great ideas might not fit in with our vision for the project and, even if we don't implement
38+
them, we greatly appreciate your input
39+
40+
## Development Setup
41+
42+
### IDE Plugins
43+
44+
The following IntelliJ / Android Studio plugins are recommended:
45+
46+
- **[Detekt](https://plugins.jetbrains.com/plugin/10761-detekt)** — highlights static analysis issues in real time as
47+
you write code
48+
- **[Ktlint](https://plugins.jetbrains.com/plugin/15057-ktlint)** — provides real-time code formatting feedback (the
49+
project enforces ktlint-compatible rules via detekt-formatting)
50+
- **[Kotest](https://plugins.jetbrains.com/plugin/14080-kotest)** — required to run individual tests from the IDE, since
51+
tests are written in Kotest `FunSpec` style
52+
53+
### Code Quality
54+
55+
Before submitting a PR, run:
56+
57+
```bash
58+
./gradlew detektAll
59+
```
60+
61+
This runs static analysis across the entire codebase and will report any violations.
62+
The CI pipeline also runs detekt automatically on pull requests and posts inline review comments.
63+
64+
The detekt configuration lives in `config/detekt/detekt.yml`. Zero violations are allowed (`maxIssues: 0`).
65+
66+
### Writing Tests
67+
68+
Tests live in `lib/src/commonTest/kotlin/` and run on all platforms.
69+
They use [Kotest](https://kotest.io/) `FunSpec` style:
70+
71+
```kotlin
72+
class MyFeatureTest : FunSpec({
73+
context("feature description") {
74+
test("specific behaviour") {
75+
// assertions
76+
}
77+
}
78+
})
79+
```
80+
81+
Install the Kotest IntelliJ plugin to run and debug individual tests from the IDE.
82+
83+
## Submitting a PR
84+
85+
We appreciate community members who are excited for our projects and willing to help improve them!
86+
87+
### Before Submitting a PR
88+
89+
If you are considering making a significant change, **please get in contact with us** before commiting a significant
90+
amount of time and effort.
91+
Even well thought out and constructed PRs sometimes do not fit into the current goals of the project and we would hate
92+
for anyone to feel their time is wasted.
93+
To discuss changes you can first [submit an issue](#opening-an-issue) documenting the bug or enhancement. Alternatively
94+
you can reach out in the [Kotlinlang touchlab-tools channel](https://kotlinlang.slack.com/archives/CTJB58X7X)
95+
96+
### When Submitting a PR
97+
98+
Please be sure to check that no tests are broken and relevant tests have been added.
99+
Include documentation updates for any changes to behavior or usage.
100+
Be as detailed as possible in your PR comments about what has changed and how to test it.
101+
102+
## Other Ways To Help
103+
104+
- Test and comment on other's contributions
105+
- Review PR's
106+
- Confirm issues and provide reproducers
107+
- Star the repository
108+
- Share the project with other developers
109+
110+
## Releasing
111+
112+
Releases are published to Maven Central via the GitHub Actions workflow defined in
113+
`.github/workflows/deployment.yml`.
114+
115+
### Version
116+
117+
The version is defined in `build-logic/src/main/kotlin/kjwt/Projects.kt`:
118+
119+
```kotlin
120+
object Projects {
121+
const val VERSION = "0.1.0"
122+
}
123+
```
124+
125+
`main` always holds the version of the **next planned release**. After a release is published,
126+
a follow-up PR is opened on `main` bumping the version to the next one.
127+
128+
### Snapshots
129+
130+
Every push to `main` automatically publishes a snapshot build to Maven Central.
131+
Snapshot artifacts have `-SNAPSHOT` appended to the version.
132+
133+
### Final Releases
134+
135+
To publish a final (non-snapshot) release:
136+
137+
1. Ensure `Projects.VERSION` on `main` is set to the version you want to release
138+
2. Manually trigger the **"Publish to Maven Central"** workflow from the GitHub Actions UI,
139+
selecting `main` as the target branch
140+
3. After the release is published, open a PR on `main` bumping `Projects.VERSION` to the next version
141+
142+
Workflow dispatch triggers set `SNAPSHOT=false`, producing a final versioned artifact.
143+
144+
### Hotfix Releases
145+
146+
> [!IMPORTANT]
147+
> Hotfix releases are handled by Touchlab developers. Community contributors should only submit PRs targeting `main`. If
148+
> your change is urgent and needs to be included in a hotfix release, please reach out in
149+
> the [Kotlinlang touchlab-tools channel](https://kotlinlang.slack.com/archives/CTJB58X7X) and add this information in
150+
> the pull request description.
151+
152+
A hotfix is a patch that needs to ship on a previous release without including unreleased changes from `main`.
153+
154+
1. **Fix on `main` first** — open a PR with the bug fix targeting `main` and get it merged.
155+
This ensures the fix is never lost from the main line.
156+
157+
2. **Create a hotfix branch from the release tag**:
158+
```bash
159+
git checkout -b hotfix/v0.1.1 v0.1.0
160+
```
161+
Use the tag of the version that needs the patch as the base.
162+
163+
3. **Cherry-pick the fix** from `main`:
164+
```bash
165+
git cherry-pick <commit-sha>
166+
```
167+
168+
4. **Bump the version** in `build-logic/src/main/kotlin/kjwt/Projects.kt` to the hotfix version
169+
(e.g., `0.1.0``0.1.1`) and commit the change.
170+
171+
5. **Publish a snapshot and smoke test** — before triggering the final release, it is recommended
172+
to publish a snapshot from the hotfix branch and validate it in a real project.
173+
Trigger the **"Publish to Maven Central"** workflow with the **Snapshot** checkbox ticked,
174+
selecting your hotfix branch as the target. Test the resulting `-SNAPSHOT` artifact,
175+
then proceed to the next step only when satisfied.
176+
177+
6. **Trigger the release** by manually running the **"Publish to Maven Central"** workflow
178+
from the GitHub Actions UI, selecting your hotfix branch as the target and leaving the
179+
**Snapshot** checkbox unticked.
180+
This publishes the artifact and creates the `v0.1.1` git tag automatically.
181+
182+
7. **Delete the hotfix branch** — the git tag is the permanent reference for the release.

build-logic/src/main/kotlin/kjwt.publish.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ plugins {
55
id("com.vanniktech.maven.publish")
66
}
77

8-
group = Projects.group
9-
version = Projects.version.let {
8+
group = Projects.GROUP
9+
version = Projects.VERSION.let {
1010
if (project.hasProperty("SNAPSHOT")) {
1111
"$it-SNAPSHOT"
1212
} else {

build-logic/src/main/kotlin/kjwt/Projects.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import org.gradle.api.artifacts.dsl.DependencyHandler
77
import org.gradle.kotlin.dsl.getByType
88

99
object Projects {
10-
const val group = "co.touchlab"
11-
const val version = "0.1.0"
10+
const val GROUP = "co.touchlab"
11+
const val VERSION = "0.1.0"
1212

1313
private enum class Type { Library, Misc }
1414

build-logic/src/main/kotlin/kjwt/docs.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fun DokkaSourceSetSpec.registerExternalDocumentation() {
3333

3434
fun DokkaExtension.registerVersioningPlugin(project: Project) {
3535
pluginsConfiguration.versioning {
36-
version.set(Projects.version)
36+
version.set(Projects.VERSION)
3737
olderVersionsDir.set(project.rootProject.projectDir.resolve("build/previous-versions"))
3838
renderVersionsNavigationOnAllPages.set(true)
3939
}

0 commit comments

Comments
 (0)