diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 0b9474d..36ec408 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -119,11 +119,12 @@ jobs: - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - name: Log in to GHCR - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 + uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3 with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + max_attempts: 3 + timeout_minutes: 2 + retry_wait_seconds: 10 + command: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - name: Free disk space uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 @@ -203,17 +204,20 @@ jobs: - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - name: Log in to GHCR - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 + uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3 with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + max_attempts: 3 + timeout_minutes: 2 + retry_wait_seconds: 10 + command: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - name: Log in to Docker Hub - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 + uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + max_attempts: 3 + timeout_minutes: 2 + retry_wait_seconds: 10 + command: echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - name: Docker metadata id: meta diff --git a/.github/workflows/promote-nightly-to-main.yml b/.github/workflows/promote-nightly-to-main.yml index 1917977..4e455c3 100644 --- a/.github/workflows/promote-nightly-to-main.yml +++ b/.github/workflows/promote-nightly-to-main.yml @@ -61,19 +61,27 @@ jobs: const headSha = branch.commit.sha; core.info(`nightly HEAD: ${headSha}`); - // A few retries in case CI hasn't materialized yet for this exact - // HEAD (e.g. nightly just synced minutes ago). + // sync-nightly.yml never creates a new commit — nightly is always + // either untouched or fast-forwarded/reset to development's exact + // SHA. So a completed CI run on 'development' at this same SHA is + // equally valid proof of health, and covers two gaps in checking + // 'nightly' alone: (1) if nightly was synced with the GITHUB_TOKEN + // fallback (doesn't trigger downstream workflows), CI never ran on + // nightly at all; (2) if nightly already matched development when + // the sync ran, no push happened, so no nightly-branch run exists + // for this SHA even with a trigger token configured. let run = null; for (let attempt = 1; attempt <= 4; attempt += 1) { const { data } = await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, workflow_id: 'ci.yml', - branch: 'nightly', status: 'completed', per_page: 20, }); - run = data.workflow_runs.find((r) => r.head_sha === headSha); + run = data.workflow_runs.find( + (r) => r.head_sha === headSha && (r.head_branch === 'nightly' || r.head_branch === 'development'), + ); if (run) break; core.info(`No completed CI run for nightly HEAD yet (attempt ${attempt}/4), waiting...`); await new Promise((resolve) => setTimeout(resolve, 15000)); diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 949ce4c..69535c6 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.2" + ".": "0.2.4" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bb39de..0a880f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [0.2.4](https://github.com/Wikid82/hestia/compare/hestia-v0.2.3...hestia-v0.2.4) (2026-08-10) + + +### Bug Fixes + +* retry GHCR and Docker Hub logins on transient denial ([88fa2e3](https://github.com/Wikid82/hestia/commit/88fa2e337e7e1685bd4dd05cd21c41e522810c3b)) + +## [0.2.3](https://github.com/Wikid82/hestia/compare/hestia-v0.2.2...hestia-v0.2.3) (2026-08-10) + + +### Bug Fixes + +* accept development-branch CI run as proof of nightly health ([7a3cf5e](https://github.com/Wikid82/hestia/commit/7a3cf5e7a3ca7473a258f9faed4bebd6aca03500)) + ## [0.2.2](https://github.com/Wikid82/hestia/compare/hestia-v0.2.1...hestia-v0.2.2) (2026-08-09) diff --git a/CLAUDE.md b/CLAUDE.md index e668014..3eaec82 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,17 @@ adding a new external dependency) before just doing it. branch in the normal checkout. Jeremy likes to build and test the app himself before merging, and a worktree puts the change somewhere he isn't already looking. -- Open PRs against `development`, not `main`. `main` is the +- Only switch/create a branch for major feature work. Small edits and + fixes happen directly on whatever branch is currently checked out — + don't branch reflexively for every change. Branch (and open a PR) when + something is a real chore that needs build/CI testing before landing. +- CI/workflow changes (`.github/workflows/*`) are committed directly to + `main` for now, since that's the branch CI actually runs on and needs + to reflect immediately — `propagate-main-to-development.yml` carries + them down to `development` automatically. Once the project is more + mature this will switch to normal PRs against `development` like + everything else; ask if it's unclear which regime is current. +- Otherwise, open PRs against `development`, not `main`. `main` is the release/stable branch; `development` is the integration branch, periodically synced back into `main`. diff --git a/package-lock.json b/package-lock.json index 8dced12..ac58bfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "hestia", - "version": "0.2.2", + "version": "0.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "hestia", - "version": "0.2.2", + "version": "0.2.4", "dependencies": { "better-sqlite3": "^13.0.3", "drizzle-orm": "^0.45.2", diff --git a/package.json b/package.json index 3c5e028..79092b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hestia", - "version": "0.2.2", + "version": "0.2.4", "private": true, "type": "module", "scripts": { diff --git a/release-please-config.json b/release-please-config.json index 5987c28..e0d7c1a 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,6 +1,8 @@ { "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", "release-type": "node", + "pull-request-header": "Here's what's new in Hestia", + "pull-request-footer": "Merge this PR to cut the release.", "packages": { ".": {} }