ci: support dev staging branch and pre-release tags in release workflow (#999)
Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,7 @@ version: 2
|
|||||||
updates:
|
updates:
|
||||||
- package-ecosystem: "gradle"
|
- package-ecosystem: "gradle"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
|
target-branch: "dev"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
open-pull-requests-limit: 25
|
open-pull-requests-limit: 25
|
||||||
@@ -35,6 +36,7 @@ updates:
|
|||||||
|
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
|
target-branch: "dev"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ env:
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, dev]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main, dev]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ name: "CodeQL Analysis"
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "dev" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "main" ]
|
branches: [ "main", "dev" ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '30 3 * * 1' # Runs at 03:30 UTC every Monday
|
- cron: '30 3 * * 1' # Runs at 03:30 UTC every Monday
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ name: Merge Conflict Detector
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, synchronize, reopened]
|
types: [opened, synchronize, reopened]
|
||||||
branches: [main]
|
branches: [main, dev]
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main, dev]
|
||||||
|
|
||||||
# Cancel in-progress runs when a new event lands — protects the expensive
|
# Cancel in-progress runs when a new event lands — protects the expensive
|
||||||
# bulk-check path. github.ref is stable per PR (refs/pull/N/merge) AND stable
|
# bulk-check path. github.ref is stable per PR (refs/pull/N/merge) AND stable
|
||||||
@@ -125,19 +125,20 @@ jobs:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Bulk check all open PRs (push to main event) ───────────
|
// ── Bulk check all open PRs (push to main/dev event) ───────────
|
||||||
// GitHub usually recomputes mergeable for every open PR at once after a
|
// GitHub usually recomputes mergeable for every open PR at once after a
|
||||||
// push, so most hit the retry loop simultaneously. Batch a few at a time
|
// push, so most hit the retry loop simultaneously. Batch a few at a time
|
||||||
// with Promise.all to bound wall-clock without hammering the API.
|
// with Promise.all to bound wall-clock without hammering the API.
|
||||||
if (context.eventName === 'push') {
|
if (context.eventName === 'push') {
|
||||||
|
const targetBranch = context.ref.replace('refs/heads/', '');
|
||||||
const { data: prs } = await github.rest.pulls.list({
|
const { data: prs } = await github.rest.pulls.list({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
state: 'open',
|
state: 'open',
|
||||||
base: 'main',
|
base: targetBranch,
|
||||||
per_page: 100,
|
per_page: 100,
|
||||||
});
|
});
|
||||||
core.info(`Checking ${prs.length} open PR(s) base on main...`);
|
core.info(`Checking ${prs.length} open PR(s) based on ${targetBranch}...`);
|
||||||
const CHUNK = 5;
|
const CHUNK = 5;
|
||||||
for (let i = 0; i < prs.length; i += CHUNK) {
|
for (let i = 0; i < prs.length; i += CHUNK) {
|
||||||
const batch = prs.slice(i, i + CHUNK);
|
const batch = prs.slice(i, i + CHUNK);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: PR Auto-Labeler
|
|||||||
on:
|
on:
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [opened, synchronize, reopened]
|
types: [opened, synchronize, reopened]
|
||||||
branches: [main]
|
branches: [main, dev]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|||||||
@@ -54,11 +54,18 @@ jobs:
|
|||||||
# Strip leading 'v' for versionName
|
# Strip leading 'v' for versionName
|
||||||
VERSION="${TAG#v}"
|
VERSION="${TAG#v}"
|
||||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||||
# versionCode: strip dots from version, pad to keep sortable
|
# versionCode: strip pre-release suffixes (e.g. 1.25.0-rc1 -> 1.25.0) and dots
|
||||||
CODE=$(echo "$VERSION" | tr -d '.' | sed 's/^0*//')
|
BASE_VERSION="${VERSION%%-*}"
|
||||||
|
CODE=$(echo "$BASE_VERSION" | tr -d '.' | sed 's/^0*//')
|
||||||
[ -z "$CODE" ] && CODE=0
|
[ -z "$CODE" ] && CODE=0
|
||||||
echo "code=$CODE" >> "$GITHUB_OUTPUT"
|
echo "code=$CODE" >> "$GITHUB_OUTPUT"
|
||||||
echo "Release: tag=$TAG version=$VERSION code=$CODE"
|
if [[ "$VERSION" == *"-"* ]]; then
|
||||||
|
PRERELEASE="true"
|
||||||
|
else
|
||||||
|
PRERELEASE="false"
|
||||||
|
fi
|
||||||
|
echo "prerelease=$PRERELEASE" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Release: tag=$TAG version=$VERSION code=$CODE prerelease=$PRERELEASE"
|
||||||
|
|
||||||
- name: Decode release keystore
|
- name: Decode release keystore
|
||||||
env:
|
env:
|
||||||
@@ -108,6 +115,6 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
release/hermes-mobile-${{ steps.version.outputs.tag }}.apk
|
release/hermes-mobile-${{ steps.version.outputs.tag }}.apk
|
||||||
release/version.txt
|
release/version.txt
|
||||||
prerelease: false
|
prerelease: ${{ steps.version.outputs.prerelease == 'true' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -220,15 +220,15 @@ Access status colors via `LocalHermesStatusColors.current.success`, not
|
|||||||
|
|
||||||
### PR-Always (ENFORCED)
|
### PR-Always (ENFORCED)
|
||||||
|
|
||||||
**Every change goes through a PR. Never push directly to `main`.**
|
**Every change goes through a PR, targeting `dev`. Never push directly to `dev` (or `main`).**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout main && git pull origin main
|
git checkout dev && git pull origin dev
|
||||||
git checkout -b fix/issue-N-description # or feat/...
|
git checkout -b fix/issue-N-description # or feat/...
|
||||||
# make changes, run ./ktlint --format
|
# make changes, run ./ktlint --format
|
||||||
git commit -m "fix(#N): description"
|
git commit -m "fix(#N): description"
|
||||||
git push -u origin HEAD
|
git push -u origin HEAD
|
||||||
gh pr create --title "fix(#N): description" --body "Closes #N"
|
gh pr create --base dev --title "fix(#N): description" --body "Closes #N"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Commit Conventions — STRICT
|
### Commit Conventions — STRICT
|
||||||
|
|||||||
+5
-5
@@ -20,17 +20,17 @@ If an open PR already covers it, review or improve that one instead of opening a
|
|||||||
|
|
||||||
## PR Workflow
|
## PR Workflow
|
||||||
|
|
||||||
All code changes must go through a pull request (PR). Directly pushing to `main` is not allowed **except for trivial changes the maintainer explicitly okays** — when in doubt, open a PR.
|
All code changes must go through a pull request (PR) targeting the `dev` staging branch. Directly pushing to `main` or `dev` is not allowed **except for trivial changes the maintainer explicitly okays** — when in doubt, open a PR.
|
||||||
|
|
||||||
1. **Pick or open an issue** to discuss the changes you want to make.
|
1. **Pick or open an issue** to discuss the changes you want to make.
|
||||||
2. **Create a branch** off `main` using the following naming convention:
|
2. **Create a branch** off `dev` using the following naming convention:
|
||||||
- Features: `feat/short-description` (optionally `feat/issue-N-description`)
|
- Features: `feat/short-description` (optionally `feat/issue-N-description`)
|
||||||
- Bug fixes: `fix/short-description` (optionally `fix/issue-N-description`)
|
- Bug fixes: `fix/short-description` (optionally `fix/issue-N-description`)
|
||||||
- CI/chore: `ci/...`, `chore/...`
|
- CI/chore: `ci/...`, `chore/...`
|
||||||
3. **Implement your changes** and format them locally (see Code Style).
|
3. **Implement your changes** and format them locally (see Code Style).
|
||||||
4. **Submit a PR** targeting the `main` branch, filling the PR template.
|
4. **Submit a PR** targeting the `dev` branch, filling the PR template.
|
||||||
5. **Ensure all CI checks pass** (ktlint, Android Lint, unit tests, build).
|
5. **Ensure all CI checks pass** (ktlint, Android Lint, unit tests, build).
|
||||||
6. **Rebase onto `main` before merge.** Maintainers squash-merge; a stale branch's version of an unrelated file can silently overwrite recent fixes on `main` when squashed. `git fetch origin main && git rebase origin/main` first.
|
6. **Rebase onto `dev` before merge.** Maintainers squash-merge; a stale branch's version of an unrelated file can silently overwrite recent fixes on `dev` when squashed. `git fetch origin dev && git rebase origin/dev` first.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ We enforce Kotlin coding conventions and Jetpack Compose best practices.
|
|||||||
Before submitting your PR, please verify:
|
Before submitting your PR, please verify:
|
||||||
|
|
||||||
- [ ] I searched open/closed PRs + issues for duplicates (see *Before You Start*).
|
- [ ] I searched open/closed PRs + issues for duplicates (see *Before You Start*).
|
||||||
- [ ] Branch is rebased onto current `main` (`git rebase origin/main`).
|
- [ ] Branch is rebased onto current `dev` (`git rebase origin/dev`).
|
||||||
- [ ] `./gradlew ktlintCheck` passes (ran `ktlintFormat` first — no hand edits).
|
- [ ] `./gradlew ktlintCheck` passes (ran `ktlintFormat` first — no hand edits).
|
||||||
- [ ] `checkColorLiterals` passes (no hardcoded Color literals outside theme/).
|
- [ ] `checkColorLiterals` passes (no hardcoded Color literals outside theme/).
|
||||||
- [ ] `./gradlew testDebugUnitTest` passes locally (or CI unit-tests job is green).
|
- [ ] `./gradlew testDebugUnitTest` passes locally (or CI unit-tests job is green).
|
||||||
|
|||||||
@@ -124,10 +124,6 @@ Tap **Sign in** on the landing screen and enter the dashboard host and port. The
|
|||||||
|
|
||||||
Have multiple gateways? Switch between them in **Settings → Connection profiles**. Each profile stores its own host, port, and token — just tap to swap.
|
Have multiple gateways? Switch between them in **Settings → Connection profiles**. Each profile stores its own host, port, and token — just tap to swap.
|
||||||
|
|
||||||
### Pairing (admin)
|
|
||||||
|
|
||||||
The **Pairing** screen lets you approve or revoke agents and services that are trying to connect to your gateway, such as Telegram or Discord sessions.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|||||||
Reference in New Issue
Block a user