test pr #11

open
opened by boltless.me targeting master from push-quxnxquxmqrz

hey make some pipelines

Changed files
+140 -81
.tangled
appview
docs
spindle
spindle
engine
+1 -5
.tangled/workflows/build.yml
··· 1 1 when: 2 - - event: ["push", "pull_request"] 2 + - event: ["push"] 3 3 branch: ["master"] 4 4 5 5 dependencies: ··· 22 22 - name: build knot 23 23 command: | 24 24 go build -o knot.out ./cmd/knot 25 - 26 - - name: build spindle 27 - command: | 28 - go build -o spindle.out ./cmd/spindle
+1 -1
.tangled/workflows/fmt.yml
··· 1 1 when: 2 - - event: ["push", "pull_request"] 2 + - event: ["push"] 3 3 branch: ["master"] 4 4 5 5 dependencies:
+2 -2
.tangled/workflows/test.yml
··· 1 1 when: 2 - - event: ["push", "pull_request"] 3 - branch: ["master"] 2 + - event: ["push"] 3 + branch: ["master", "test-ci"] 4 4 5 5 dependencies: 6 6 nixpkgs:
+17 -12
appview/db/issues.go
··· 9 9 ) 10 10 11 11 type Issue struct { 12 + ID int64 12 13 RepoAt syntax.ATURI 13 14 OwnerDid string 14 15 IssueId int ··· 65 66 66 67 issue.IssueId = nextId 67 68 68 - _, err = tx.Exec(` 69 + res, err := tx.Exec(` 69 70 insert into issues (repo_at, owner_did, issue_id, title, body) 70 71 values (?, ?, ?, ?, ?) 71 72 `, issue.RepoAt, issue.OwnerDid, issue.IssueId, issue.Title, issue.Body) 72 73 if err != nil { 73 74 return err 74 75 } 76 + 77 + lastID, err := res.LastInsertId() 78 + if err != nil { 79 + return err 80 + } 81 + issue.ID = lastID 75 82 76 83 if err := tx.Commit(); err != nil { 77 84 return err ··· 89 96 var issueAt string 90 97 err := e.QueryRow(`select issue_at from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&issueAt) 91 98 return issueAt, err 92 - } 93 - 94 - func GetIssueId(e Execer, repoAt syntax.ATURI) (int, error) { 95 - var issueId int 96 - err := e.QueryRow(`select next_issue_id from repo_issue_seqs where repo_at = ?`, repoAt).Scan(&issueId) 97 - return issueId - 1, err 98 99 } 99 100 100 101 func GetIssueOwnerDid(e Execer, repoAt syntax.ATURI, issueId int) (string, error) { ··· 114 115 ` 115 116 with numbered_issue as ( 116 117 select 118 + i.id, 117 119 i.owner_did, 118 120 i.issue_id, 119 121 i.created, ··· 132 134 i.id, i.owner_did, i.issue_id, i.created, i.title, i.body, i.open 133 135 ) 134 136 select 137 + id, 135 138 owner_did, 136 139 issue_id, 137 140 created, ··· 153 156 var issue Issue 154 157 var createdAt string 155 158 var metadata IssueMetadata 156 - err := rows.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) 159 + err := rows.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) 157 160 if err != nil { 158 161 return nil, err 159 162 } ··· 182 185 183 186 rows, err := e.Query( 184 187 `select 188 + i.id, 185 189 i.owner_did, 186 190 i.repo_at, 187 191 i.issue_id, ··· 213 217 var issueCreatedAt, repoCreatedAt string 214 218 var repo Repo 215 219 err := rows.Scan( 220 + &issue.ID, 216 221 &issue.OwnerDid, 217 222 &issue.RepoAt, 218 223 &issue.IssueId, ··· 257 262 } 258 263 259 264 func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) { 260 - query := `select owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` 265 + query := `select id, owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` 261 266 row := e.QueryRow(query, repoAt, issueId) 262 267 263 268 var issue Issue 264 269 var createdAt string 265 - err := row.Scan(&issue.OwnerDid, &createdAt, &issue.Title, &issue.Body, &issue.Open) 270 + err := row.Scan(&issue.ID, &issue.OwnerDid, &createdAt, &issue.Title, &issue.Body, &issue.Open) 266 271 if err != nil { 267 272 return nil, err 268 273 } ··· 277 282 } 278 283 279 284 func GetIssueWithComments(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, []Comment, error) { 280 - query := `select owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` 285 + query := `select id, owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` 281 286 row := e.QueryRow(query, repoAt, issueId) 282 287 283 288 var issue Issue 284 289 var createdAt string 285 - err := row.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) 290 + err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) 286 291 if err != nil { 287 292 return nil, nil, err 288 293 }
+7 -13
appview/issues/issues.go
··· 687 687 return 688 688 } 689 689 690 - err = db.NewIssue(tx, &db.Issue{ 690 + issue := &db.Issue{ 691 691 RepoAt: f.RepoAt, 692 692 Title: title, 693 693 Body: body, 694 694 OwnerDid: user.Did, 695 - }) 696 - if err != nil { 697 - log.Println("failed to create issue", err) 698 - rp.pages.Notice(w, "issues", "Failed to create issue.") 699 - return 700 695 } 701 - 702 - issueId, err := db.GetIssueId(rp.db, f.RepoAt) 696 + err = db.NewIssue(tx, issue) 703 697 if err != nil { 704 - log.Println("failed to get issue id", err) 698 + log.Println("failed to create issue", err) 705 699 rp.pages.Notice(w, "issues", "Failed to create issue.") 706 700 return 707 701 } ··· 723 717 Title: title, 724 718 Body: &body, 725 719 Owner: user.Did, 726 - IssueId: int64(issueId), 720 + IssueId: int64(issue.IssueId), 727 721 }, 728 722 }, 729 723 }) ··· 733 727 return 734 728 } 735 729 736 - err = db.SetIssueAt(rp.db, f.RepoAt, issueId, resp.Uri) 730 + err = db.SetIssueAt(rp.db, f.RepoAt, issue.IssueId, resp.Uri) 737 731 if err != nil { 738 732 log.Println("failed to set issue at", err) 739 733 rp.pages.Notice(w, "issues", "Failed to create issue.") ··· 744 738 err = rp.posthog.Enqueue(posthog.Capture{ 745 739 DistinctId: user.Did, 746 740 Event: "new_issue", 747 - Properties: posthog.Properties{"repo_at": f.RepoAt.String(), "issue_id": issueId}, 741 + Properties: posthog.Properties{"repo_at": f.RepoAt.String(), "issue_id": issue.IssueId}, 748 742 }) 749 743 if err != nil { 750 744 log.Println("failed to enqueue posthog event:", err) 751 745 } 752 746 } 753 747 754 - rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issueId)) 748 + rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) 755 749 return 756 750 } 757 751 }
+37
appview/notify/merged_notifier.go
··· 1 + package notify 2 + 3 + import ( 4 + "context" 5 + 6 + "tangled.sh/tangled.sh/core/appview/db" 7 + ) 8 + 9 + type mergedNotifier struct { 10 + notifiers []Notifier 11 + } 12 + 13 + func NewMergedNotifier(notifiers ...Notifier) Notifier { 14 + return &mergedNotifier{ 15 + notifiers, 16 + } 17 + } 18 + 19 + var _ Notifier = &mergedNotifier{} 20 + 21 + func (m *mergedNotifier) NewIssue(ctx context.Context, issue db.Issue) { 22 + for _, notifier := range m.notifiers { 23 + notifier.NewIssue(ctx, issue) 24 + } 25 + } 26 + 27 + func (m *mergedNotifier) NewIssueComment(ctx context.Context, comment db.Comment) { 28 + for _, notifier := range m.notifiers { 29 + notifier.NewIssueComment(ctx, comment) 30 + } 31 + } 32 + 33 + func (m *mergedNotifier) NewPullComment(ctx context.Context, comment db.PullComment) { 34 + for _, notifier := range m.notifiers { 35 + notifier.NewPullComment(ctx, comment) 36 + } 37 + }
+14
appview/notify/notifier.go
··· 1 + package notify 2 + 3 + import ( 4 + "context" 5 + 6 + "tangled.sh/tangled.sh/core/appview/db" 7 + ) 8 + 9 + type Notifier interface { 10 + NewIssue(ctx context.Context, issue db.Issue) 11 + NewIssueComment(ctx context.Context, comment db.Comment) 12 + 13 + NewPullComment(ctx context.Context, comment db.PullComment) 14 + }
+1 -1
appview/pages/templates/timeline.html
··· 108 108 {{ $starrerHandle := index $.DidHandleMap .Star.StarredByDid }} 109 109 {{ $repoOwnerHandle := index $.DidHandleMap .Star.Repo.Did }} 110 110 <div class="flex items-center"> 111 - <p class="text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2"> 111 + <p class="text-gray-600 dark:text-gray-300 flex items-center gap-2"> 112 112 {{ template "user/fragments/picHandle" $starrerHandle }} 113 113 starred 114 114 <a
+1 -1
appview/state/router.go
··· 191 191 } 192 192 193 193 func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler { 194 - issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog) 194 + issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog, s.notifier) 195 195 return issues.Router(mw) 196 196 197 197 }
+6
appview/state/state.go
··· 25 25 "tangled.sh/tangled.sh/core/appview/config" 26 26 "tangled.sh/tangled.sh/core/appview/db" 27 27 "tangled.sh/tangled.sh/core/appview/idresolver" 28 + "tangled.sh/tangled.sh/core/appview/notify" 28 29 "tangled.sh/tangled.sh/core/appview/oauth" 29 30 "tangled.sh/tangled.sh/core/appview/pages" 30 31 "tangled.sh/tangled.sh/core/appview/reporesolver" ··· 37 38 38 39 type State struct { 39 40 db *db.DB 41 + notifier notify.Notifier 40 42 oauth *oauth.OAuth 41 43 enforcer *rbac.Enforcer 42 44 tidClock syntax.TIDClock ··· 134 136 } 135 137 spindlestream.Start(ctx) 136 138 139 + notifier := notify.NewMergedNotifier( 140 + ) 141 + 137 142 state := &State{ 138 143 d, 144 + notifier, 139 145 oauth, 140 146 enforcer, 141 147 clock,
+2 -4
docs/spindle/hosting.md
··· 31 31 2. **Build the Spindle binary.** 32 32 33 33 ```shell 34 - cd core 35 - go mod download 36 - go build -o cmd/spindle/spindle cmd/spindle/main.go 34 + go build -o spindle core/spindle/server.go 37 35 ``` 38 36 39 37 3. **Run the Spindle binary.** 40 38 41 39 ```shell 42 - ./cmd/spindle/spindle 40 + ./spindle 43 41 ``` 44 42 45 43 Spindle will now start, connect to the Jetstream server, and begin processing pipelines.
+50 -41
flake.nix
··· 53 53 }: let 54 54 supportedSystems = ["x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin"]; 55 55 forAllSystems = nixpkgs.lib.genAttrs supportedSystems; 56 - nixpkgsFor = forAllSystems (system: nixpkgs.legacyPackages.${system}); 56 + nixpkgsFor = forAllSystems (system: 57 + import nixpkgs { 58 + inherit system; 59 + overlays = [self.overlays.default]; 60 + }); 57 61 inherit (gitignore.lib) gitignoreSource; 58 - mkPackageSet = pkgs: let 62 + in { 63 + overlays.default = final: prev: let 59 64 goModHash = "sha256-SLi+nALwCd/Lzn3aljwPqCo2UaM9hl/4OAjcHQLt2Bk="; 60 - sqlite-lib = pkgs.callPackage ./nix/pkgs/sqlite-lib.nix { 61 - inherit (pkgs) gcc; 62 - inherit sqlite-lib-src; 65 + appviewDeps = { 66 + inherit htmx-src htmx-ws-src lucide-src inter-fonts-src ibm-plex-mono-src goModHash gitignoreSource; 63 67 }; 64 - genjwks = pkgs.callPackage ./nix/pkgs/genjwks.nix {inherit goModHash gitignoreSource;}; 65 - lexgen = pkgs.callPackage ./nix/pkgs/lexgen.nix {inherit indigo;}; 66 - appview = pkgs.callPackage ./nix/pkgs/appview.nix { 67 - inherit sqlite-lib htmx-src htmx-ws-src lucide-src inter-fonts-src ibm-plex-mono-src goModHash gitignoreSource; 68 + knotDeps = { 69 + inherit goModHash gitignoreSource; 68 70 }; 69 - spindle = pkgs.callPackage ./nix/pkgs/spindle.nix {inherit sqlite-lib goModHash gitignoreSource;}; 70 - knot-unwrapped = pkgs.callPackage ./nix/pkgs/knot-unwrapped.nix {inherit sqlite-lib goModHash gitignoreSource;}; 71 - knot = pkgs.callPackage ./nix/pkgs/knot.nix {inherit knot-unwrapped;}; 72 - in { 73 - inherit lexgen appview spindle knot-unwrapped knot sqlite-lib genjwks; 74 - }; 75 - in { 76 - overlays.default = final: prev: mkPackageSet final; 71 + spindleDeps = { 72 + inherit goModHash gitignoreSource; 73 + }; 74 + mkPackageSet = pkgs: { 75 + lexgen = pkgs.callPackage ./nix/pkgs/lexgen.nix {inherit indigo;}; 76 + appview = pkgs.callPackage ./nix/pkgs/appview.nix appviewDeps; 77 + knot = pkgs.callPackage ./nix/pkgs/knot.nix {}; 78 + spindle = pkgs.callPackage ./nix/pkgs/spindle.nix spindleDeps; 79 + knot-unwrapped = pkgs.callPackage ./nix/pkgs/knot-unwrapped.nix knotDeps; 80 + sqlite-lib = pkgs.callPackage ./nix/pkgs/sqlite-lib.nix { 81 + inherit (pkgs) gcc; 82 + inherit sqlite-lib-src; 83 + }; 84 + genjwks = pkgs.callPackage ./nix/pkgs/genjwks.nix {inherit goModHash gitignoreSource;}; 85 + }; 86 + in 87 + mkPackageSet final; 77 88 78 89 packages = forAllSystems (system: let 79 90 pkgs = nixpkgsFor.${system}; 80 - packages = mkPackageSet pkgs; 81 - staticPackages = mkPackageSet pkgs.pkgsStatic; 82 - crossPackages = mkPackageSet pkgs.pkgsCross.gnu64.pkgsStatic; 91 + staticPkgs = pkgs.pkgsStatic; 92 + crossPkgs = pkgs.pkgsCross.gnu64.pkgsStatic; 83 93 in { 84 - appview = packages.appview; 85 - lexgen = packages.lexgen; 86 - knot = packages.knot; 87 - knot-unwrapped = packages.knot-unwrapped; 88 - spindle = packages.spindle; 89 - genjwks = packages.genjwks; 90 - sqlite-lib = packages.sqlite-lib; 94 + appview = pkgs.appview; 95 + lexgen = pkgs.lexgen; 96 + knot = pkgs.knot; 97 + knot-unwrapped = pkgs.knot-unwrapped; 98 + spindle = pkgs.spindle; 99 + genjwks = pkgs.genjwks; 100 + sqlite-lib = pkgs.sqlite-lib; 91 101 92 - pkgsStatic-appview = staticPackages.appview; 93 - pkgsStatic-knot = staticPackages.knot; 94 - pkgsStatic-knot-unwrapped = staticPackages.knot-unwrapped; 95 - pkgsStatic-spindle = staticPackages.spindle; 96 - pkgsStatic-sqlite-lib = staticPackages.sqlite-lib; 102 + pkgsStatic-appview = staticPkgs.appview; 103 + pkgsStatic-knot = staticPkgs.knot; 104 + pkgsStatic-knot-unwrapped = staticPkgs.knot-unwrapped; 105 + pkgsStatic-spindle = staticPkgs.spindle; 106 + pkgsStatic-sqlite-lib = staticPkgs.sqlite-lib; 97 107 98 - pkgsCross-gnu64-pkgsStatic-appview = crossPackages.appview; 99 - pkgsCross-gnu64-pkgsStatic-knot = crossPackages.knot; 100 - pkgsCross-gnu64-pkgsStatic-knot-unwrapped = crossPackages.knot-unwrapped; 101 - pkgsCross-gnu64-pkgsStatic-spindle = crossPackages.spindle; 108 + pkgsCross-gnu64-pkgsStatic-appview = crossPkgs.appview; 109 + pkgsCross-gnu64-pkgsStatic-knot = crossPkgs.knot; 110 + pkgsCross-gnu64-pkgsStatic-knot-unwrapped = crossPkgs.knot-unwrapped; 111 + pkgsCross-gnu64-pkgsStatic-spindle = crossPkgs.spindle; 102 112 }); 103 - defaultPackage = forAllSystems (system: self.packages.${system}.appview); 104 - formatter = forAllSystems (system: nixpkgsFor.${system}.alejandra); 113 + defaultPackage = forAllSystems (system: nixpkgsFor.${system}.appview); 114 + formatter = forAllSystems (system: nixpkgsFor."${system}".alejandra); 105 115 devShells = forAllSystems (system: let 106 116 pkgs = nixpkgsFor.${system}; 107 - packages' = self.packages.${system}; 108 117 staticShell = pkgs.mkShell.override { 109 118 stdenv = pkgs.pkgsStatic.stdenv; 110 119 }; ··· 115 124 pkgs.air 116 125 pkgs.gopls 117 126 pkgs.httpie 127 + pkgs.lexgen 118 128 pkgs.litecli 119 129 pkgs.websocat 120 130 pkgs.tailwindcss 121 131 pkgs.nixos-shell 122 132 pkgs.redis 123 - packages'.lexgen 124 133 ]; 125 134 shellHook = '' 126 135 mkdir -p appview/pages/static/{fonts,icons} ··· 130 139 cp -f ${inter-fonts-src}/web/InterVariable*.woff2 appview/pages/static/fonts/ 131 140 cp -f ${inter-fonts-src}/web/InterDisplay*.woff2 appview/pages/static/fonts/ 132 141 cp -f ${ibm-plex-mono-src}/fonts/complete/woff2/IBMPlexMono-Regular.woff2 appview/pages/static/fonts/ 133 - export TANGLED_OAUTH_JWKS="$(${packages'.genjwks}/bin/genjwks)" 142 + export TANGLED_OAUTH_JWKS="$(${pkgs.genjwks}/bin/genjwks)" 134 143 ''; 135 144 env.CGO_ENABLED = 1; 136 145 };
+1 -1
spindle/engine/envs_test.go
··· 34 34 if got == nil { 35 35 got = EnvVars{} 36 36 } 37 - assert.ElementsMatch(t, tt.want, got) 37 + assert.Equal(t, tt.want, got) 38 38 }) 39 39 } 40 40 }