diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index b20d949..d28e404 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -54,7 +54,7 @@ jobs: if: env.SOURCES_APP == 'true' uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 with: - app-id: ${{ secrets.SOURCES_APP_ID }} + client-id: Iv23li1IcazrCq1yAVQt # spin-stack-website-sources' client ID, public: app-id is deprecated private-key: ${{ secrets.SOURCES_APP_KEY }} owner: spin-stack repositories: spin diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index a2b2994..c88f8e0 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -48,7 +48,7 @@ jobs: - id: sources-token uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 with: - app-id: ${{ secrets.SOURCES_APP_ID }} + client-id: Iv23li1IcazrCq1yAVQt # spin-stack-website-sources' client ID, public: app-id is deprecated private-key: ${{ secrets.SOURCES_APP_KEY }} owner: spin-stack repositories: spin,spin-terraform-aws,spin-machine,spinbox.dev-deploy @@ -73,7 +73,7 @@ jobs: - id: sync-token uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 with: - app-id: ${{ secrets.SYNC_APP_ID }} + client-id: Iv23liTD5gzpSkUHViuO # spin-stack-website-sync's client ID, public: app-id is deprecated private-key: ${{ secrets.SYNC_APP_KEY }} owner: spin-stack repositories: website @@ -101,7 +101,7 @@ jobs: - id: sources-token uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 with: - app-id: ${{ secrets.SOURCES_APP_ID }} + client-id: Iv23li1IcazrCq1yAVQt # spin-stack-website-sources' client ID, public: app-id is deprecated private-key: ${{ secrets.SOURCES_APP_KEY }} owner: spin-stack repositories: spin,spin-terraform-aws,spin-machine,spinbox.dev-deploy diff --git a/tools/sources/assets.go b/tools/sources/assets.go index 8b7af9b..f7b3c95 100644 --- a/tools/sources/assets.go +++ b/tools/sources/assets.go @@ -50,6 +50,29 @@ const stamp = ".release" // one, and nothing a path could climb out of the directory with. var shotName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*\.png$`) +// ready is whether e's release tag already holds the asset the site takes of it: a bump moves +// to a release only once it does. site-shots.yml puts it there about an hour after Release, and +// a sync in that hour would otherwise move the pin and then fail on the missing screenshots; it +// stays instead, and the next day's takes the release. +func ready(ctx context.Context, gh *github.Client, e versions.Entry, tag string) (bool, error) { + a, ok := assets[e.Name] + if !ok { + return true, nil + } + var rel struct { + Assets []struct{ Name string } `json:"assets"` + } + if err := gh.Get(ctx, "/repos/"+strings.TrimPrefix(e.Source, "https://github.com/")+"/releases/tags/"+tag, &rel); err != nil { + return false, err + } + for _, have := range rel.Assets { + if have.Name == a.name { + return true, nil + } + } + return false, nil +} + // fetchAsset unpacks a's asset of e's release into dir. A directory already stamped with e's // release and pin is left as it is, so a run after the one with the token needs none. A release // without the asset fails, saying how to give it one: the site never keeps another release's diff --git a/tools/sources/assets_test.go b/tools/sources/assets_test.go index d91d2ca..a6870f4 100644 --- a/tools/sources/assets_test.go +++ b/tools/sources/assets_test.go @@ -129,3 +129,20 @@ func TestScreenshotsThatAreNotTheReleasesFail(t *testing.T) { } } } + +// A bump waits for the release's screenshots: a release without them yet is not ready, one with +// them is, and a source the site takes no asset of is ready as it is. +func TestABumpWaitsForTheReleasesScreenshots(t *testing.T) { + gh := releases(t, map[string][]byte{"v20261025.01": nil, "v20261026.01": []byte("shots")}) + for tag, want := range map[string]bool{"v20261025.01": false, "v20261026.01": true} { + if got, err := ready(context.Background(), gh, spinAt("v20261024.01"), tag); err != nil || got != want { + t.Errorf("ready(%s) = %v, %v; want %v", tag, got, err, want) + } + } + if ok, err := ready(context.Background(), gh, versions.Entry{Name: "spin-terraform-aws"}, "v20261025.01"); err != nil || !ok { + t.Errorf("a source with no asset: ready = %v, %v; want true", ok, err) + } + if _, err := ready(context.Background(), gh, spinAt("v20261024.01"), "v20990101.01"); err == nil { + t.Error("ready took a 404 for an answer") + } +} diff --git a/tools/sources/bump.go b/tools/sources/bump.go index 32bec46..abf554d 100644 --- a/tools/sources/bump.go +++ b/tools/sources/bump.go @@ -33,6 +33,13 @@ func bumpFile(ctx context.Context, file string, names []string, gh *github.Clien fmt.Printf("%s: stays at %s %s\n", st.Entry.Name, st.Entry.Version, st.Entry.Pin) continue } + if ok, err := ready(ctx, gh, st.Entry, to); err != nil { + return fmt.Errorf("%s: %w", st.Entry.Name, err) + } else if !ok { + fmt.Printf("%s: stays at %s %s: %s has no %s yet, which site-shots.yml puts on it about an hour after Release; the next sync takes it\n", + st.Entry.Name, st.Entry.Version, st.Entry.Pin, to, assets[st.Entry.Name].name) + continue + } e, b, err := upstream.Bump(ctx, v, st.Entry.Name, to) if err != nil { return err