diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..813e826 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +nix/deps.nix linguist-vendored +nix/sources.nix linguist-vendored diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d2cfb0f..10979a8 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,10 +5,10 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - name: Set up Go 1.12 + - name: Set up Go 1.14 uses: actions/setup-go@v1 with: - go-version: 1.12 + go-version: 1.14 id: go - name: Check out code into the Go module directory uses: actions/checkout@v1 diff --git a/Dockerfile b/Dockerfile index 75c98f5..6695ebb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM xena/go:1.13.6 AS build +FROM xena/go:1.14 AS build ENV GOPROXY https://cache.greedo.xeserv.us COPY . /site WORKDIR /site diff --git a/blog/patron-page-2020-02-29.markdown b/blog/patron-page-2020-02-29.markdown new file mode 100644 index 0000000..fb37150 --- /dev/null +++ b/blog/patron-page-2020-02-29.markdown @@ -0,0 +1,52 @@ +--- +title: "New Site Feature: Patron Thanks Page" +date: 2020-02-29 +--- + +# New Site Feature: Patron Thanks Page + +I've added a [patron thanks page](/patrons) to my site. I've been getting a +significant amount of money per month from my patrons and I feel this is a good +way to acknowledge them and thank them for their patronage. I wanted to have it +be _as simple as possible_, so I made it fetch a list of dollar amounts. + +Here are some things I learned while writing this: + +- If you are going to interact with the patreon API in go, use + [`github.com/mxpv/patreon-go`][patreongo], not `gopkg.in/mxpv/patreon-go.v1` + or `gopkg.in/mxpv/patreon-go.v2`. The packages on gopkg.in are NOT compatible + with Go modules in very bizarre ways. +- When using refresh tokens in OAuth2, do not set the expiry date to be + _negative_ like the patreon-go examples show. This will brick your token and + make you have to reprovision it. +- Patreon clients can either be for API version 1 or API version 2. There is no + way to have a Patreon token that works for both API versions. +- The patreon-go package only supports API version 1 and doesn't document this + anywhere. +- Patreon's error messages are vague and not helpful when trying to figure out + that you broke your token with a negative expiry date. +- I may need to set the Patreon information every month for the rest of the time + I maintain this site code. This could get odd. I made a guide for myself in + the [docs folder of the site repo][docsfolder]. +- The Patreon API doesn't let you submit new posts. I wanted to add Patreon to + my syndication server, but apparently that's impossible. My [RSS + feed](/blog.rss), [Atom feed](/blog.atom) and [JSON feed](/blog.json) should + let you keep up to date in the meantime. + +Let me know how you like this. I went back and forth on displaying monetary +amounts on that page, but ultimately decided not to show them there for +confidentiality reasons. If this is a bad idea, please let me know and I can put +the money amounts back. + +I'm working on a more detailed post about [pa'i][pahi] that includes benchmarks +for some artificial and realistic workloads. I'm also working on integrating it +into the [wamscloud][wasmcloud] prototype, but it's fairly slow going at the +moment. + +Be well. + +[patreongo]: https://github.com/mxpv/patreon-go +[docsfolder]: https://github.com/Xe/site/tree/master/docs +[pahi]: https://github.com/Xe/pahi +[wasmcloud]: https://tulpa.dev/within/wasmcloud + diff --git a/cmd/site/main.go b/cmd/site/main.go index da0207d..3a534f0 100644 --- a/cmd/site/main.go +++ b/cmd/site/main.go @@ -13,6 +13,7 @@ import ( "christine.website/cmd/site/internal/middleware" "christine.website/jsonfeed" "github.com/gorilla/feeds" + _ "github.com/joho/godotenv/autoload" "github.com/povilasv/prommod" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -60,6 +61,7 @@ type Site struct { Gallery blog.Posts Resume template.HTML Series []string + patrons []string rssFeed *feeds.Feed jsonFeed *jsonfeed.Feed @@ -84,10 +86,20 @@ func (s *Site) ServeHTTP(w http.ResponseWriter, r *http.Request) { middleware.RequestID(s.xffmw.Handler(ex.HTTPLog(s.mux))).ServeHTTP(w, r) } -var arbDate = time.Date(2020, time.January, 9, 0, 0, 0, 0, time.UTC) +var arbDate = time.Date(2020, time.February, 29, 0, 0, 0, 0, time.UTC) // Build creates a new Site instance or fails. func Build() (*Site, error) { + pc, err := NewPatreonClient() + if err != nil { + return nil, err + } + + pledges, err := GetPledges(pc) + if err != nil { + return nil, err + } + smi := sitemap.New() smi.Add(&sitemap.URL{ Loc: "https://christine.website/resume", @@ -107,6 +119,12 @@ func Build() (*Site, error) { ChangeFreq: sitemap.Monthly, }) + smi.Add(&sitemap.URL{ + Loc: "https://christine.website/patrons", + LastMod: &arbDate, + ChangeFreq: sitemap.Weekly, + }) + smi.Add(&sitemap.URL{ Loc: "https://christine.website/blog", LastMod: &arbDate, @@ -143,6 +161,8 @@ func Build() (*Site, error) { }, mux: http.NewServeMux(), xffmw: xffmw, + + patrons: pledges, } posts, err := blog.LoadPosts("./blog/", "blog") @@ -215,6 +235,7 @@ func Build() (*Site, error) { s.renderTemplatePage("index.html", nil).ServeHTTP(w, r) }) s.mux.Handle("/metrics", promhttp.Handler()) + s.mux.Handle("/patrons", middleware.Metrics("patrons", s.renderTemplatePage("patrons.html", s.patrons))) s.mux.Handle("/resume", middleware.Metrics("resume", s.renderTemplatePage("resume.html", s.Resume))) s.mux.Handle("/blog", middleware.Metrics("blog", s.renderTemplatePage("blogindex.html", s.Posts))) s.mux.Handle("/talks", middleware.Metrics("talks", s.renderTemplatePage("talkindex.html", s.Talks))) diff --git a/cmd/site/patreon.go b/cmd/site/patreon.go new file mode 100644 index 0000000..c8e7dba --- /dev/null +++ b/cmd/site/patreon.go @@ -0,0 +1,112 @@ +package main + +import ( + "context" + "fmt" + "net/http" + "os" + "sort" + "time" + + "github.com/mxpv/patreon-go" + "golang.org/x/oauth2" + "within.website/ln" +) + +func NewPatreonClient() (*patreon.Client, error) { + for _, name := range []string{"CLIENT_ID", "CLIENT_SECRET", "ACCESS_TOKEN", "REFRESH_TOKEN"} { + if os.Getenv("PATREON_"+name) == "" { + return nil, fmt.Errorf("wanted envvar PATREON_%s", name) + } + } + + config := oauth2.Config{ + ClientID: os.Getenv("PATREON_CLIENT_ID"), + ClientSecret: os.Getenv("PATREON_CLIENT_SECRET"), + Endpoint: oauth2.Endpoint{ + AuthURL: patreon.AuthorizationURL, + TokenURL: patreon.AccessTokenURL, + }, + Scopes: []string{"users", "campaigns", "pledges", "pledges-to-me", "my-campaign"}, + } + + token := oauth2.Token{ + AccessToken: os.Getenv("PATREON_ACCESS_TOKEN"), + RefreshToken: os.Getenv("PATREON_REFRESH_TOKEN"), + // Must be non-nil, otherwise token will not be expired + Expiry: time.Now().Add(90 * 24 * time.Hour), + } + + tc := config.Client(context.Background(), &token) + + trans := tc.Transport + tc.Transport = lnLoggingTransport{next: trans} + client := patreon.NewClient(tc) + + return client, nil +} + +func GetPledges(pc *patreon.Client) ([]string, error) { + campaign, err := pc.FetchCampaign() + if err != nil { + return nil, fmt.Errorf("campaign fetch error: %w", err) + } + + campaignID := campaign.Data[0].ID + + cursor := "" + var result []string + + for { + pledgesResponse, err := pc.FetchPledges(campaignID, patreon.WithPageSize(25), patreon.WithCursor(cursor)) + if err != nil { + return nil, err + } + + users := make(map[string]*patreon.User) + for _, item := range pledgesResponse.Included.Items { + u, ok := item.(*patreon.User) + if !ok { + continue + } + + users[u.ID] = u + } + + for _, pledge := range pledgesResponse.Data { + pid := pledge.Relationships.Patron.Data.ID + patronFullName := users[pid].Attributes.FullName + + result = append(result, patronFullName) + } + + cursor = pledgesResponse.Links.Next + if cursor == "" { + break + } + } + + sort.Strings(result) + return result, nil +} + +type lnLoggingTransport struct{ next http.RoundTripper } + +func (l lnLoggingTransport) RoundTrip(r *http.Request) (*http.Response, error) { + ctx := r.Context() + f := ln.F{ + "url": r.URL.String(), + "has_token": r.Header.Get("Authorization") != "", + } + + resp, err := l.next.RoundTrip(r) + if err != nil { + return nil, err + } + + f["status"] = resp.Status + + ln.Log(ctx, f) + + return resp, nil +} diff --git a/docs/patron-page.org b/docs/patron-page.org new file mode 100644 index 0000000..974fa6f --- /dev/null +++ b/docs/patron-page.org @@ -0,0 +1,77 @@ +#+TITLE: Patron Page + +#+BEGIN: clocktable :maxlevel 2 :emphasize nil :scope file +#+CAPTION: Clock summary at [2020-02-29 Sat 20:47] +| Headline | Time | | +|------------------------------------------+--------+------| +| *Total time* | *1:36* | | +|------------------------------------------+--------+------| +| figure out how to get list of patrons | 1:05 | | +| \_ get patreon credentials into site | | 0:08 | +| \_ figure out patreon id of my campaign | | 0:25 | +| \_ get list of patrons | | 0:25 | +| \_ show in HTML | | 0:07 | +| figure out how to handle the secrets... | 0:03 | | +| Links | 0:28 | | +| \_ Announcement blogpost | | 0:28 | +#+END: clocktable + +* DONE figure out how to get list of patrons + CLOSED: [2020-02-29 Sat 20:18] +** DONE get patreon credentials into site + CLOSED: [2020-02-29 Sat 19:14] + :LOGBOOK: + CLOCK: [2020-02-29 Sat 19:06]--[2020-02-29 Sat 19:14] => 0:08 + :END: + +Added envvars + ++ =PATREON_CLIENT_ID= ++ =PATREON_CLIENT_SECRET= ++ =PATREON_ACCESS_TOKEN= ++ =PATREON_REFRESH_TOKEN= +** DONE figure out patreon id of my campaign + CLOSED: [2020-02-29 Sat 19:39] + :LOGBOOK: + CLOCK: [2020-02-29 Sat 19:14]--[2020-02-29 Sat 19:39] => 0:25 + :END: +** DONE get list of patrons + CLOSED: [2020-02-29 Sat 20:05] + :LOGBOOK: + CLOCK: [2020-02-29 Sat 19:40]--[2020-02-29 Sat 20:05] => 0:25 + :END: +** DONE show in HTML + CLOSED: [2020-02-29 Sat 20:12] + :LOGBOOK: + CLOCK: [2020-02-29 Sat 20:05]--[2020-02-29 Sat 20:12] => 0:07 + :END: +* DONE figure out how to handle the secrets for patreon + CLOSED: [2020-02-29 Sat 20:18] + :LOGBOOK: + CLOCK: [2020-02-29 Sat 20:15]--[2020-02-29 Sat 20:18] => 0:03 + :END: +Currently putting them in the dyson secret store, will need to figure out +something else for dhall. +* DONE Links + CLOSED: [2020-02-29 Sat 20:47] +** DONE Add link in footer + CLOSED: [2020-02-29 Sat 20:13] +** DONE Add into sitemap + CLOSED: [2020-02-29 Sat 20:13] +** DONE Announcement blogpost + CLOSED: [2020-02-29 Sat 20:47] + :LOGBOOK: + CLOCK: [2020-02-29 Sat 20:37]--[2020-02-29 Sat 20:47] => 0:10 + CLOCK: [2020-02-29 Sat 20:19]--[2020-02-29 Sat 20:37] => 0:18 + :END: + +* How to refresh credentials + +1. Go to https://www.patreon.com/portal/registration/register-clients +2. Open Mi (API v1) +3. Hit "Refresh Token" +4. Copy access token and refresh token to + ~/code/within-terraform-secret/christinewebsite.env as =PATREON_ACCESS_TOKEN= + and =PATREON_REFRESH_TOKEN= +5. Commit file to repo and push +6. Retry deployment of the site diff --git a/go.mod b/go.mod index b8d12c3..741f853 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module christine.website require ( github.com/celrenheit/sandflake v0.0.0-20190410195419-50a943690bc2 github.com/gorilla/feeds v1.1.1 + github.com/joho/godotenv v1.3.0 + github.com/mxpv/patreon-go v0.0.0-20190917022727-646111f1d983 github.com/povilasv/prommod v0.0.12 github.com/prometheus/client_golang v1.4.1 github.com/russross/blackfriday v2.0.0+incompatible @@ -10,6 +12,7 @@ require ( github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/snabb/sitemap v1.0.0 github.com/stretchr/testify v1.4.0 + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d gopkg.in/yaml.v2 v2.2.8 within.website/ln v0.8.0 ) diff --git a/go.sum b/go.sum index d02a053..ec11951 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -32,6 +33,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY= github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -49,6 +52,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxpv/patreon-go v0.0.0-20190917022727-646111f1d983 h1:r32TFg+FHLnoF8PCqCQNp+R9EjMBuP62FXkD/Eqp9Us= +github.com/mxpv/patreon-go v0.0.0-20190917022727-646111f1d983/go.mod h1:ksYjm2GAbGlgIP7jO9Q5/AdyE4MwwEbgQ+lFMx3hyiM= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -59,8 +64,6 @@ github.com/povilasv/prommod v0.0.12/go.mod h1:GnuK7wLoVBwZXj8bhbJNx/xFSldy7Q49A4 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.4.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFYyOi8zA+Y8= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -99,10 +102,14 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -116,6 +123,8 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= diff --git a/deps.nix b/nix/deps.nix similarity index 91% rename from deps.nix rename to nix/deps.nix index 3d4b10e..63b0a56 100644 --- a/deps.nix +++ b/nix/deps.nix @@ -1,5 +1,14 @@ # file generated from go.mod using vgo2nix (https://github.com/adisbladis/vgo2nix) [ + { + goPackagePath = "cloud.google.com/go"; + fetch = { + type = "git"; + url = "https://code.googlesource.com/gocloud"; + rev = "v0.34.0"; + sha256 = "1kclgclwar3r37zbvb9gg3qxbgzkb50zk3s9778zlh2773qikmai"; + }; + } { goPackagePath = "github.com/alecthomas/template"; fetch = { @@ -126,6 +135,15 @@ sha256 = "1lwqibra4hyzx0jhaz12rfhfnw73bmdf8cn9r51nqidk8k7zf7sg"; }; } + { + goPackagePath = "github.com/joho/godotenv"; + fetch = { + type = "git"; + url = "https://github.com/joho/godotenv"; + rev = "v1.3.0"; + sha256 = "0ri8if0pc3x6jg4c3i8wr58xyfpxkwmcjk3rp8gb398a1aa3gpjm"; + }; + } { goPackagePath = "github.com/json-iterator/go"; fetch = { @@ -225,6 +243,15 @@ sha256 = "0nbrnpk7bkmqg9mzwsxlm0y8m7s9qd9phr1q30qlx2qmdmz7c1mf"; }; } + { + goPackagePath = "github.com/mxpv/patreon-go"; + fetch = { + type = "git"; + url = "https://github.com/mxpv/patreon-go"; + rev = "646111f1d983"; + sha256 = "0cksf3andl8z04lychay2j0l8wrpdq7j5pdb6zy5yr4990iab6aa"; + }; + } { goPackagePath = "github.com/pkg/errors"; fetch = { @@ -378,6 +405,15 @@ sha256 = "18xj31h70m7xxb7gc86n9i21w6d7djbjz67zfaljm4jqskz6hxkf"; }; } + { + goPackagePath = "golang.org/x/oauth2"; + fetch = { + type = "git"; + url = "https://go.googlesource.com/oauth2"; + rev = "bf48bf16ab8d"; + sha256 = "1sirdib60zwmh93kf9qrx51r8544k1p9rs5mk0797wibz3m4mrdg"; + }; + } { goPackagePath = "golang.org/x/sync"; fetch = { @@ -414,6 +450,15 @@ sha256 = "1yjfi1bk9xb81lqn85nnm13zz725wazvrx3b50hx19qmwg7a4b0c"; }; } + { + goPackagePath = "google.golang.org/appengine"; + fetch = { + type = "git"; + url = "https://github.com/golang/appengine"; + rev = "v1.4.0"; + sha256 = "06zl7w4sxgdq2pl94wy9ncii6h0z3szl4xpqds0sv3b3wbdlhbnn"; + }; + } { goPackagePath = "gopkg.in/alecthomas/kingpin.v2"; fetch = { diff --git a/shell.nix b/shell.nix index 6abe8a7..f88232b 100644 --- a/shell.nix +++ b/shell.nix @@ -2,10 +2,26 @@ let sources = import ./nix/sources.nix; pkgs = import sources.nixpkgs { }; niv = (import sources.niv { }).niv; - dhall-yaml = - (import sources.easy-dhall-nix { inherit pkgs; }).dhall-yaml-simple; + dhallpkgs = import sources.easy-dhall-nix { inherit pkgs; }; + dhall-yaml = dhallpkgs.dhall-yaml-simple; + dhall = dhallpkgs.dhall-simple; xepkgs = import sources.xepkgs { inherit pkgs; }; vgo2nix = import sources.vgo2nix { inherit pkgs; }; -in pkgs.mkShell { - buildInputs = [ pkgs.go xepkgs.gopls dhall-yaml niv vgo2nix ]; +in with pkgs; +with xepkgs; +mkShell { + buildInputs = [ + # Go tools + go + goimports + gopls + vgo2nix + + # kubernetes deployment + dhall + dhall-yaml + + # dependency manager + niv + ]; } diff --git a/site.nix b/site.nix index 59996a8..157429e 100644 --- a/site.nix +++ b/site.nix @@ -8,7 +8,7 @@ buildGoPackage rec { version = "latest"; goPackagePath = "christine.website"; src = ./.; - goDeps = ./deps.nix; + goDeps = ./nix/deps.nix; allowGoReference = false; preBuild = '' diff --git a/templates/base.html b/templates/base.html index 7ebf2e1..ad0d099 100644 --- a/templates/base.html +++ b/templates/base.html @@ -68,7 +68,7 @@