diff options
-rw-r--r-- | .github/workflows/lifecycle.yml | 189 | ||||
-rw-r--r-- | .github/workflows/trunk.yml | 32 | ||||
-rw-r--r-- | cache/repo_cache_test.go | 276 | ||||
-rw-r--r-- | misc/completion/bash/git-bug | 6 | ||||
-rw-r--r-- | misc/completion/generate.go | 6 | ||||
-rw-r--r-- | nix/checks/pinact.nix | 15 |
6 files changed, 189 insertions, 335 deletions
diff --git a/.github/workflows/lifecycle.yml b/.github/workflows/lifecycle.yml deleted file mode 100644 index 1d06ebd4..00000000 --- a/.github/workflows/lifecycle.yml +++ /dev/null @@ -1,189 +0,0 @@ ---- -name: lifecycle - -on: - issues: - types: - - assigned - - closed - - demilestoned - - milestoned - - pinned - - unpinned - - reopened - issue_comment: - types: - - created - pull_request: - types: - - assigned - - auto_merge_enabled - - converted_to_draft - - demilestoned - - enqueued - - milestoned - - ready_for_review - - reopened - - synchronize - pull_request_review: - types: - - submitted - - dismissed - schedule: - - cron: '17 3 * * *' # every day at 03:17 UTC - -concurrency: - group: lifecycle-${{ github.event.issue.number || github.event.pull_request.number || 'scheduled' }} - cancel-in-progress: false - -jobs: - auto-label: - name: auto-label - if: github.event_name != 'schedule' - runs-on: ubuntu-latest - permissions: - contents: read - issues: write - pull-requests: write - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - sparse-checkout: | - .github/actions/auto-label - - - name: "restore cache: node modules" - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - with: - path: .github/actions/auto-label/node_modules - key: auto-label-${{ runner.os }}-${{ hashFiles('.github/actions/auto-label/package-lock.json') }} - restore-keys: | - auto-label-${{ runner.os }}- - - - name: "install dependencies for //.github/actions/auto-label" - working-directory: .github/actions/auto-label - run: npm ci - - - name: "add label for pinned or milestoned item: lifecycle/pinned" - if: github.event.action == 'pinned' || github.event.action == 'milestoned' - uses: ./.github/actions/auto-label - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - add: lifecycle/pinned - remove: | - lifecycle/idle - lifecycle/dormant - - - name: "remove label for unpinned or demilestoned item: lifecycle/pinned" - if: github.event.action == 'unpinned' || github.event.action == 'demilestoned' - uses: ./.github/actions/auto-label - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - remove: lifecycle/pinned - - - name: "remove lifecycle label due to activity" - if: github.event.action != 'pinned' && github.event.action != 'milestoned' - uses: ./.github/actions/auto-label - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - remove: | - lifecycle/idle - lifecycle/dormant - - idle-sweeper: - name: idle-sweeper - if: github.event_name == 'schedule' - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - env: - ISSUE_MESSAGE_DETAILS: | - <br /><strong>Issues will <em>not</em> be automatically closed due to - inactivity.</strong> - <hr /> - <details> - <summary>Learn more</summary> - - This bot triages issues in order to help the maintainers identify what - needs attention, according to the following lifecycle rules: - - - After 90 days of inactivity, <code>lifecycle/idle</code> is applied - - After 180 days of inactivity, <code>lifecycle/dormant</code> is applied - - The following actions remove the inactive status: - - - Removing the <code>lifecycle/*</code> label from this issue - - Commenting on this issue - - Adding a new assignee to this issue - - Reopening this issue - - Adding this issue to a milestone - - Pinning this issue to the top of the issue board - - To avoid automatic lifecycle management of this issue, maintainers can - add the <code>lifecycle/pinned</code> label. - </details> - PR_MESSAGE_DETAILS: | - <br /><strong>Pull requests will <em>not</em> be closed automatically - due to inactivity.</strong> - - <details> - <summary>Learn more</summary> - This bot triages pull requests in order to help the maintainers identify - what needs attention, according to the following lifecycle rules: - - - After 90 days of inactivity, <code>lifecycle/idle</code> is applied - - After 90 days of inactivity, <code>lifecycle/dormant</code> is applied - - The following actions remove the inactive status: - - - Removing the <code>lifecycle/*</code> label from this pull request - - Commenting on this pull request - - Submitting a review for this pull request - - Adding a new assignee to this pull request - - Reopening this pull request - - Adding this pull request to a milestone - - Converting this pull request to a draft - - Setting this pull request as "ready to review" (not a draft) - - Enabling auto-merge, or adding this pull request to the merge queue - - To avoid automatic lifecycle management of this pull request, - maintainers can add the <code>lifecycle/pinned</code> label. - </details> - steps: - - name: "inactivity check: 90 days" - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 - with: - days-before-close: -1 - days-before-stale: 90 - exempt-all-milestones: true - exempt-issue-labels: lifecycle/idle,lifecycle/dormant,lifecycle/pinned - exempt-pr-labels: lifecycle/idle,lifecycle/dormant,lifecycle/pinned - labels-to-remove-when-stale: lifecycle/active - stale-issue-label: lifecycle/idle - stale-issue-message: | - Pinging maintainers. This issue has been inactive for 90 days. - ${{ env.ISSUE_MESSAGE_DETAILS }} - stale-pr-label: lifecycle/idle - stale-pr-message: | - Pinging maintainers. This pull request has been inactive for 90 days. - ${{ env.PR_MESSAGE_DETAILS }} - - - name: "inactivity check: 180 days" - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 - with: - days-before-close: -1 - days-before-stale: 180 - exempt-all-milestones: true - labels-to-remove-when-stale: lifecycle/idle - only-labels: lifecycle/idle - stale-issue-label: lifecycle/dormant - stale-issue-message: |- - Pinging maintainers. This issue has been inactive for 180 days. - ${{ env.ISSUE_MESSAGE_DETAILS }} - stale-pr-label: lifecycle/dormant - stale-pr-message: |- - Pinging maintainers. This pull request has been inactive for 180 days. - ${{ env.PR_MESSAGE_DETAILS }} diff --git a/.github/workflows/trunk.yml b/.github/workflows/trunk.yml index 6abf3ed4..7e5243ac 100644 --- a/.github/workflows/trunk.yml +++ b/.github/workflows/trunk.yml @@ -43,3 +43,35 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} comment-on-alert: true auto-push: true + + mirror: + if: > + github.ref == 'refs/heads/master' && github.repository == 'git-bug/git-bug' && github.run_attempt == '1' + permissions: + contents: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + # we use a custom deploy key in order to allow the workflow to bypass + # branch protection rules. without this, pushing will be rejected + - name: setup authentication + env: + SSH_AUTH_SOCK: /tmp/ssh-agent.sock + run: | + mkdir -p ~/.ssh + echo "${{ secrets.TRUNK_MIRROR_KEY }}" > ~/.ssh/id_rsa + chmod 0600 ~/.ssh/id_rsa + ssh-agent -a $SSH_AUTH_SOCK > /dev/null + ssh-add ~/.ssh/id_rsa + + - name: push to trunk + env: + SSH_AUTH_SOCK: /tmp/ssh-agent.sock + run: |- + git config user.name git-bug-bot + git config user.email no-reply@git-bug.org + git remote set-url origin git@github.com:git-bug/git-bug.git + git push --atomic origin HEAD:refs/heads/trunk diff --git a/cache/repo_cache_test.go b/cache/repo_cache_test.go index 48704783..e974a3c5 100644 --- a/cache/repo_cache_test.go +++ b/cache/repo_cache_test.go @@ -11,169 +11,175 @@ import ( "github.com/git-bug/git-bug/entities/bug" "github.com/git-bug/git-bug/entities/identity" "github.com/git-bug/git-bug/entity" + "github.com/git-bug/git-bug/internal/test" "github.com/git-bug/git-bug/query" "github.com/git-bug/git-bug/repository" ) func TestCache(t *testing.T) { - repo := repository.CreateGoGitTestRepo(t, false) - - indexCount := func(t *testing.T, name string) uint64 { - t.Helper() - - idx, err := repo.GetIndex(name) - require.NoError(t, err) - count, err := idx.DocCount() - require.NoError(t, err) - - return count - } + f := test.NewFlaky(t, &test.FlakyOptions{ + MaxAttempts: 5, + }) - cache, err := NewRepoCacheNoEvents(repo) - require.NoError(t, err) + f.Run(func(t testing.TB) { + repo := repository.CreateGoGitTestRepo(t, false) + indexCount := func(t testing.TB, name string) uint64 { + t.Helper() - // Create, set and get user identity - iden1, err := cache.Identities().New("René Descartes", "rene@descartes.fr") - require.NoError(t, err) - err = cache.SetUserIdentity(iden1) - require.NoError(t, err) - userIden, err := cache.GetUserIdentity() - require.NoError(t, err) - require.Equal(t, iden1.Id(), userIden.Id()) + idx, err := repo.GetIndex(name) + require.NoError(t, err) + count, err := idx.DocCount() + require.NoError(t, err) - // it's possible to create two identical identities - iden2, err := cache.Identities().New("René Descartes", "rene@descartes.fr") - require.NoError(t, err) + return count + } - // Two identical identities yield a different id - require.NotEqual(t, iden1.Id(), iden2.Id()) + cache, err := NewRepoCacheNoEvents(repo) + require.NoError(t, err) - // There is now two identities in the cache - require.Len(t, cache.Identities().AllIds(), 2) - require.Len(t, cache.identities.excerpts, 2) - require.Len(t, cache.identities.cached, 2) - require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) - require.Equal(t, uint64(0), indexCount(t, bug.Namespace)) + // Create, set and get user identity + iden1, err := cache.Identities().New("René Descartes", "rene@descartes.fr") + require.NoError(t, err) + err = cache.SetUserIdentity(iden1) + require.NoError(t, err) + userIden, err := cache.GetUserIdentity() + require.NoError(t, err) + require.Equal(t, iden1.Id(), userIden.Id()) - // Create a bug - bug1, _, err := cache.Bugs().New("title", "message") - require.NoError(t, err) + // it's possible to create two identical identities + iden2, err := cache.Identities().New("René Descartes", "rene@descartes.fr") + require.NoError(t, err) - // It's possible to create two identical bugs - bug2, _, err := cache.Bugs().New("title", "marker") - require.NoError(t, err) + // Two identical identities yield a different id + require.NotEqual(t, iden1.Id(), iden2.Id()) - // two identical bugs yield a different id - require.NotEqual(t, bug1.Id(), bug2.Id()) + // There is now two identities in the cache + require.Len(t, cache.Identities().AllIds(), 2) + require.Len(t, cache.identities.excerpts, 2) + require.Len(t, cache.identities.cached, 2) + require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) + require.Equal(t, uint64(0), indexCount(t, bug.Namespace)) - // There is now two bugs in the cache - require.Len(t, cache.Bugs().AllIds(), 2) - require.Len(t, cache.bugs.excerpts, 2) - require.Len(t, cache.bugs.cached, 2) - require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) - require.Equal(t, uint64(2), indexCount(t, bug.Namespace)) + // Create a bug + bug1, _, err := cache.Bugs().New("title", "message") + require.NoError(t, err) - // Resolving - _, err = cache.Identities().Resolve(iden1.Id()) - require.NoError(t, err) - _, err = cache.Identities().ResolveExcerpt(iden1.Id()) - require.NoError(t, err) - _, err = cache.Identities().ResolvePrefix(iden1.Id().String()[:10]) - require.NoError(t, err) + // It's possible to create two identical bugs + bug2, _, err := cache.Bugs().New("title", "marker") + require.NoError(t, err) - _, err = cache.Bugs().Resolve(bug1.Id()) - require.NoError(t, err) - _, err = cache.Bugs().ResolveExcerpt(bug1.Id()) - require.NoError(t, err) - _, err = cache.Bugs().ResolvePrefix(bug1.Id().String()[:10]) - require.NoError(t, err) + // two identical bugs yield a different id + require.NotEqual(t, bug1.Id(), bug2.Id()) - // Querying - q, err := query.Parse("status:open author:descartes sort:edit-asc") - require.NoError(t, err) - res, err := cache.Bugs().Query(q) - require.NoError(t, err) - require.Len(t, res, 2) + // There is now two bugs in the cache + require.Len(t, cache.Bugs().AllIds(), 2) + require.Len(t, cache.bugs.excerpts, 2) + require.Len(t, cache.bugs.cached, 2) + require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) + require.Equal(t, uint64(2), indexCount(t, bug.Namespace)) - q, err = query.Parse("status:open marker") // full-text search - require.NoError(t, err) - res, err = cache.Bugs().Query(q) - require.NoError(t, err) - require.Len(t, res, 1) + // Resolving + _, err = cache.Identities().Resolve(iden1.Id()) + require.NoError(t, err) + _, err = cache.Identities().ResolveExcerpt(iden1.Id()) + require.NoError(t, err) + _, err = cache.Identities().ResolvePrefix(iden1.Id().String()[:10]) + require.NoError(t, err) - // Close - require.NoError(t, cache.Close()) - require.Empty(t, cache.bugs.cached) - require.Empty(t, cache.bugs.excerpts) - require.Empty(t, cache.identities.cached) - require.Empty(t, cache.identities.excerpts) + _, err = cache.Bugs().Resolve(bug1.Id()) + require.NoError(t, err) + _, err = cache.Bugs().ResolveExcerpt(bug1.Id()) + require.NoError(t, err) + _, err = cache.Bugs().ResolvePrefix(bug1.Id().String()[:10]) + require.NoError(t, err) - // Reload, only excerpt are loaded, but as we need to load the identities used in the bugs - // to check the signatures, we also load the identity used above - cache, err = NewRepoCacheNoEvents(repo) - require.NoError(t, err) + // Querying + q, err := query.Parse("status:open author:descartes sort:edit-asc") + require.NoError(t, err) + res, err := cache.Bugs().Query(q) + require.NoError(t, err) + require.Len(t, res, 2) - require.Len(t, cache.bugs.cached, 0) - require.Len(t, cache.bugs.excerpts, 2) - require.Len(t, cache.identities.cached, 0) - require.Len(t, cache.identities.excerpts, 2) - require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) - require.Equal(t, uint64(2), indexCount(t, bug.Namespace)) + q, err = query.Parse("status:open marker") // full-text search + require.NoError(t, err) + res, err = cache.Bugs().Query(q) + require.NoError(t, err) + require.Len(t, res, 1) - // Resolving load from the disk - _, err = cache.Identities().Resolve(iden1.Id()) - require.NoError(t, err) - _, err = cache.Identities().ResolveExcerpt(iden1.Id()) - require.NoError(t, err) - _, err = cache.Identities().ResolvePrefix(iden1.Id().String()[:10]) - require.NoError(t, err) + // Close + require.NoError(t, cache.Close()) + require.Empty(t, cache.bugs.cached) + require.Empty(t, cache.bugs.excerpts) + require.Empty(t, cache.identities.cached) + require.Empty(t, cache.identities.excerpts) + + // Reload, only excerpt are loaded, but as we need to load the identities used in the bugs + // to check the signatures, we also load the identity used above + cache, err = NewRepoCacheNoEvents(repo) + require.NoError(t, err) - _, err = cache.Bugs().Resolve(bug1.Id()) - require.NoError(t, err) - _, err = cache.Bugs().ResolveExcerpt(bug1.Id()) - require.NoError(t, err) - _, err = cache.Bugs().ResolvePrefix(bug1.Id().String()[:10]) - require.NoError(t, err) + require.Len(t, cache.bugs.cached, 0) + require.Len(t, cache.bugs.excerpts, 2) + require.Len(t, cache.identities.cached, 0) + require.Len(t, cache.identities.excerpts, 2) + require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) + require.Equal(t, uint64(2), indexCount(t, bug.Namespace)) - require.Len(t, cache.bugs.cached, 1) - require.Len(t, cache.bugs.excerpts, 2) - require.Len(t, cache.identities.cached, 1) - require.Len(t, cache.identities.excerpts, 2) - require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) - require.Equal(t, uint64(2), indexCount(t, bug.Namespace)) + // Resolving load from the disk + _, err = cache.Identities().Resolve(iden1.Id()) + require.NoError(t, err) + _, err = cache.Identities().ResolveExcerpt(iden1.Id()) + require.NoError(t, err) + _, err = cache.Identities().ResolvePrefix(iden1.Id().String()[:10]) + require.NoError(t, err) - // Remove + RemoveAll - err = cache.Identities().Remove(iden1.Id().String()[:10]) - require.NoError(t, err) - err = cache.Bugs().Remove(bug1.Id().String()[:10]) - require.NoError(t, err) - require.Len(t, cache.bugs.cached, 0) - require.Len(t, cache.bugs.excerpts, 1) - require.Len(t, cache.identities.cached, 0) - require.Len(t, cache.identities.excerpts, 1) - require.Equal(t, uint64(1), indexCount(t, identity.Namespace)) - require.Equal(t, uint64(1), indexCount(t, bug.Namespace)) + _, err = cache.Bugs().Resolve(bug1.Id()) + require.NoError(t, err) + _, err = cache.Bugs().ResolveExcerpt(bug1.Id()) + require.NoError(t, err) + _, err = cache.Bugs().ResolvePrefix(bug1.Id().String()[:10]) + require.NoError(t, err) - _, err = cache.Identities().New("René Descartes", "rene@descartes.fr") - require.NoError(t, err) - _, _, err = cache.Bugs().NewRaw(iden2, time.Now().Unix(), "title", "message", nil, nil) - require.NoError(t, err) + require.Len(t, cache.bugs.cached, 1) + require.Len(t, cache.bugs.excerpts, 2) + require.Len(t, cache.identities.cached, 1) + require.Len(t, cache.identities.excerpts, 2) + require.Equal(t, uint64(2), indexCount(t, identity.Namespace)) + require.Equal(t, uint64(2), indexCount(t, bug.Namespace)) - err = cache.RemoveAll() - require.NoError(t, err) - require.Len(t, cache.bugs.cached, 0) - require.Len(t, cache.bugs.excerpts, 0) - require.Len(t, cache.identities.cached, 0) - require.Len(t, cache.identities.excerpts, 0) - require.Equal(t, uint64(0), indexCount(t, identity.Namespace)) - require.Equal(t, uint64(0), indexCount(t, bug.Namespace)) + // Remove + RemoveAll + err = cache.Identities().Remove(iden1.Id().String()[:10]) + require.NoError(t, err) + err = cache.Bugs().Remove(bug1.Id().String()[:10]) + require.NoError(t, err) + require.Len(t, cache.bugs.cached, 0) + require.Len(t, cache.bugs.excerpts, 1) + require.Len(t, cache.identities.cached, 0) + require.Len(t, cache.identities.excerpts, 1) + require.Equal(t, uint64(1), indexCount(t, identity.Namespace)) + require.Equal(t, uint64(1), indexCount(t, bug.Namespace)) + + _, err = cache.Identities().New("René Descartes", "rene@descartes.fr") + require.NoError(t, err) + _, _, err = cache.Bugs().NewRaw(iden2, time.Now().Unix(), "title", "message", nil, nil) + require.NoError(t, err) - // Close - require.NoError(t, cache.Close()) - require.Empty(t, cache.bugs.cached) - require.Empty(t, cache.bugs.excerpts) - require.Empty(t, cache.identities.cached) - require.Empty(t, cache.identities.excerpts) + err = cache.RemoveAll() + require.NoError(t, err) + require.Len(t, cache.bugs.cached, 0) + require.Len(t, cache.bugs.excerpts, 0) + require.Len(t, cache.identities.cached, 0) + require.Len(t, cache.identities.excerpts, 0) + require.Equal(t, uint64(0), indexCount(t, identity.Namespace)) + require.Equal(t, uint64(0), indexCount(t, bug.Namespace)) + + // Close + require.NoError(t, cache.Close()) + require.Empty(t, cache.bugs.cached) + require.Empty(t, cache.bugs.excerpts) + require.Empty(t, cache.identities.cached) + require.Empty(t, cache.identities.excerpts) + }) } func TestCachePushPull(t *testing.T) { diff --git a/misc/completion/bash/git-bug b/misc/completion/bash/git-bug index 42263e09..49c7c77b 100644 --- a/misc/completion/bash/git-bug +++ b/misc/completion/bash/git-bug @@ -352,11 +352,11 @@ _git_bug() { __git-bug_init_completion -n "=:" || return fi - # START PATCH - # replace in the array ("git","bug", ...) to ("git-bug", ...) and adjust the index in cword + # START PATCH + # replace in the array ("git","bug", ...) to ("git-bug", ...) and adjust the index in cword words=("git-bug" "${words[@]:2}") cword=$(($cword-1)) - # END PATCH + # END PATCH __git-bug_debug __git-bug_debug "========= starting completion logic ==========" diff --git a/misc/completion/generate.go b/misc/completion/generate.go index 245c561c..b64c1034 100644 --- a/misc/completion/generate.go +++ b/misc/completion/generate.go @@ -66,11 +66,11 @@ _git_bug() { __git-bug_init_completion -n "=:" || return fi - # START PATCH - # replace in the array ("git","bug", ...) to ("git-bug", ...) and adjust the index in cword + # START PATCH + # replace in the array ("git","bug", ...) to ("git-bug", ...) and adjust the index in cword words=("git-bug" "${words[@]:2}") cword=$(($cword-1)) - # END PATCH + # END PATCH __git-bug_debug __git-bug_debug "========= starting completion logic ==========" diff --git a/nix/checks/pinact.nix b/nix/checks/pinact.nix index c032bc9f..109bd14f 100644 --- a/nix/checks/pinact.nix +++ b/nix/checks/pinact.nix @@ -1,7 +1,12 @@ { pkgs, src }: -pkgs.writeShellApplication { - name = "pinact"; - runtimeInputs = with pkgs; [ pinact ]; - text = "pinact run --check --verify"; -} +pkgs.runCommand "pinact" + { + inherit src; + nativeBuildInputs = with pkgs; [ pinact ]; + } + '' + cd "$src" + pinact run --check --verify + touch "$out" + '' |