chore(ci): improving CI reliability when caching (#11501)

This fixes a case where potentially some static files get not properly
treated as inputs in the hash for nx cache calculation.

Also it fixes a problem where the assets.mdx get sorted randomly each
generation.

Factors in some overlap from
https://github.com/zitadel/zitadel/pull/11447

---------

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Florian Forster
2026-02-04 07:02:52 +00:00
committed by GitHub
co-authored by Copilot
parent 0999e44821
commit 04c58c5b3f
4 changed files with 135 additions and 15 deletions
+2
View File
@@ -68,6 +68,8 @@ jobs:
NX_DAEMON: "false"
NX_DISABLE_DB: "true"
run: pnpm nx affected --nxBail --targets lint test build --exclude @zitadel/docs
- name: Check for uncommitted changes (Codegen mismatch)
run: git diff --exit-code
- name: Suggest Pipeline Fix By Nx Cloud AI
if: failure() || cancelled()
env:
+5 -2
View File
@@ -342,9 +342,12 @@
"runtime": "go env GOARCH"
},
"{workspaceRoot}/internal/statik/generate.go",
"{workspaceRoot}/internal/static/**/*",
"{workspaceRoot}/internal/notification/statik/generate.go",
"{workspaceRoot}/internal/notification/static/**/*",
"{workspaceRoot}/internal/api/ui/login/static/resources/generate.go",
"{workspaceRoot}/internal/api/ui/login/statik/generate.go"
"{workspaceRoot}/internal/api/ui/login/statik/generate.go",
"{workspaceRoot}/internal/api/ui/login/static/**/*"
],
"outputs": [
"{workspaceRoot}/internal/statik/statik.go",
@@ -361,7 +364,7 @@
"command": "mkdir -p apps/docs/content/apis/assets && go run internal/api/assets/generator/asset_generator.go -directory=internal/api/assets/generator/ -assets=apps/docs/content/apis/assets/assets.mdx",
"cache": true,
"inputs": [
"{workspaceRoot}/internal/api/assets/generator/asset_generator.go"
"{workspaceRoot}/internal/api/assets/generator/**/*"
],
"outputs": [
"{workspaceRoot}/internal/api/assets/authz.go",
+67
View File
@@ -2,26 +2,43 @@
title: zitadel/assets
---
{/*
Code generated by assets generator. DO NOT EDIT.
This file is checked in to support building docs without a Go environment.
*/}
## AssetsService
### UploadDefaultLabelPolicyFont()
> UploadDefaultLabelPolicyFont()
POST: /instance/policy/label/font
### GetDefaultLabelPolicyFont()
> GetDefaultLabelPolicyFont()
GET: /instance/policy/label/font
### GetPreviewDefaultLabelPolicyFont()
> GetPreviewDefaultLabelPolicyFont()
GET: /instance/policy/label/font/_preview
### UploadDefaultLabelPolicyIcon()
> UploadDefaultLabelPolicyIcon()
@@ -33,6 +50,8 @@ POST: /instance/policy/label/icon
> UploadDefaultLabelPolicyIconDark()
POST: /instance/policy/label/icon/dark
### GetDefaultLabelPolicyIcon()
@@ -45,6 +64,8 @@ GET: /instance/policy/label/icon
> GetDefaultLabelPolicyIconDark()
GET: /instance/policy/label/icon/dark
### GetPreviewDefaultLabelPolicyIcon()
@@ -57,6 +78,10 @@ GET: /instance/policy/label/icon/_preview
> GetPreviewDefaultLabelPolicyIconDark()
GET: /instance/policy/label/icon/dark/_preview
### UploadDefaultLabelPolicyLogo()
@@ -69,6 +94,8 @@ POST: /instance/policy/label/logo
> UploadDefaultLabelPolicyLogoDark()
POST: /instance/policy/label/logo/dark
### GetDefaultLabelPolicyLogo()
@@ -81,6 +108,8 @@ GET: /instance/policy/label/logo
> GetDefaultLabelPolicyLogoDark()
GET: /instance/policy/label/logo/dark
### GetPreviewDefaultLabelPolicyLogo()
@@ -93,6 +122,12 @@ GET: /instance/policy/label/logo/_preview
> GetPreviewDefaultLabelPolicyLogoDark()
GET: /instance/policy/label/logo/dark/_preview
### UploadOrgLabelPolicyFont()
@@ -100,18 +135,26 @@ GET: /instance/policy/label/logo/dark/_preview
POST: /org/policy/label/font
### GetOrgLabelPolicyFont()
> GetOrgLabelPolicyFont()
GET: /org/policy/label/font
### GetPreviewOrgLabelPolicyFont()
> GetPreviewOrgLabelPolicyFont()
GET: /org/policy/label/font/_preview
### UploadOrgLabelPolicyIcon()
> UploadOrgLabelPolicyIcon()
@@ -123,6 +166,8 @@ POST: /org/policy/label/icon
> UploadOrgLabelPolicyIconDark()
POST: /org/policy/label/icon/dark
### GetOrgLabelPolicyIcon()
@@ -135,6 +180,8 @@ GET: /org/policy/label/icon
> GetOrgLabelPolicyIconDark()
GET: /org/policy/label/icon/dark
### GetPreviewOrgLabelPolicyIcon()
@@ -147,6 +194,10 @@ GET: /org/policy/label/icon/_preview
> GetPreviewOrgLabelPolicyIconDark()
GET: /org/policy/label/icon/dark/_preview
### UploadOrgLabelPolicyLogo()
@@ -159,6 +210,8 @@ POST: /org/policy/label/logo
> UploadOrgLabelPolicyLogoDark()
POST: /org/policy/label/logo/dark
### GetOrgLabelPolicyLogo()
@@ -171,6 +224,8 @@ GET: /org/policy/label/logo
> GetOrgLabelPolicyLogoDark()
GET: /org/policy/label/logo/dark
### GetPreviewOrgLabelPolicyLogo()
@@ -183,6 +238,12 @@ GET: /org/policy/label/logo/_preview
> GetPreviewOrgLabelPolicyLogoDark()
GET: /org/policy/label/logo/dark/_preview
### UploadMyUserAvatar()
@@ -190,8 +251,14 @@ GET: /org/policy/label/logo/dark/_preview
POST: /users/me/avatar
### GetMyUserAvatar()
> GetMyUserAvatar()
GET: /users/me/avatar
@@ -4,6 +4,7 @@ import (
"flag"
"io"
"os"
"sort"
"text/template"
"github.com/zitadel/logging"
@@ -97,6 +98,48 @@ type Service struct {
Methods map[string]Method
}
type SortedService struct {
Prefix string
Methods []SortedMethod
}
type SortedMethod struct {
Name string
Method
}
func (s Services) toSorted() []SortedService {
keys := make([]string, 0, len(s))
for k := range s {
keys = append(keys, k)
}
sort.Strings(keys)
sorted := make([]SortedService, len(keys))
for i, k := range keys {
sorted[i] = SortedService{
Prefix: s[k].Prefix,
Methods: s[k].toSortedMethods(),
}
}
return sorted
}
func (s Service) toSortedMethods() []SortedMethod {
keys := make([]string, 0, len(s.Methods))
for k := range s.Methods {
keys = append(keys, k)
}
sort.Strings(keys)
sorted := make([]SortedMethod, len(keys))
for i, k := range keys {
sorted[i] = SortedMethod{
Name: k,
Method: s.Methods[k],
}
}
return sorted
}
func GenerateAssetHandler(configFilePath, handlerPrefix string, authz, router, docs io.Writer) {
conf := new(struct {
Services Services
@@ -113,12 +156,12 @@ func GenerateAssetHandler(configFilePath, handlerPrefix string, authz, router, d
GoPkgName string
Name string
Prefix string
Services Services
Services []SortedService
}{
GoPkgName: "assets",
Name: "AssetsService",
Prefix: handlerPrefix,
Services: conf.Services,
Services: conf.Services.toSorted(),
}
err = tmplAuthz.Execute(authz, data)
logging.Log("ASSETS-BHngj").OnError(err).Fatal("cannot generate authz")
@@ -180,11 +223,11 @@ type {{.Name}} interface {
Storage() static.Storage
{{ range $service := .Services}}
{{ range $methodName, $method := .Methods}}
{{ range $method := .Methods}}
{{ range $handler := .Handlers}}
{{$handler.Name}}{{$methodName}}() {{if $handler.MethodReturn}}{{$handler.MethodReturn}}{{end}}
{{$handler.Name}}{{$method.Name}}() {{if $handler.MethodReturn}}{{$handler.MethodReturn}}{{end}}
{{ if $method.HasDarkMode }}
{{$handler.Name}}{{$methodName}}Dark() {{if $handler.MethodReturn}}{{$handler.MethodReturn}}{{end}}
{{$handler.Name}}{{$method.Name}}Dark() {{if $handler.MethodReturn}}{{$handler.MethodReturn}}{{end}}
{{ end }}
{{ end }}
{{ end }}
@@ -196,11 +239,11 @@ func RegisterRoutes(router *mux.Router, s {{.Name}}) {
router.Use(s.AuthInterceptor().Handler)
{{ range $service := .Services}}
{{ range $methodName, $method := .Methods}}
{{ range $method := .Methods}}
{{ range $handler := .Handlers}}
router.Path("{{$service.Prefix}}{{$method.Path}}{{$handler.PathSuffix}}").Methods("{{$handler.Method}}").HandlerFunc({{if $handler.HandlerType}}{{$handler.HandlerType}}(s, {{end}}s.{{$handler.Name}}{{$methodName}}(){{if $handler.HandlerType}}){{end}})
router.Path("{{$service.Prefix}}{{$method.Path}}{{$handler.PathSuffix}}").Methods("{{$handler.Method}}").HandlerFunc({{if $handler.HandlerType}}{{$handler.HandlerType}}(s, {{end}}s.{{$handler.Name}}{{$method.Name}}(){{if $handler.HandlerType}}){{end}})
{{ if $method.HasDarkMode }}
router.Path("{{$service.Prefix}}{{$method.Path}}/dark{{$handler.PathSuffix}}").Methods("{{$handler.Method}}").HandlerFunc({{if $handler.HandlerType}}{{$handler.HandlerType}}(s, {{end}}s.{{$handler.Name}}{{$methodName}}Dark(){{if $handler.HandlerType}}){{end}})
router.Path("{{$service.Prefix}}{{$method.Path}}/dark{{$handler.PathSuffix}}").Methods("{{$handler.Method}}").HandlerFunc({{if $handler.HandlerType}}{{$handler.HandlerType}}(s, {{end}}s.{{$handler.Name}}{{$method.Name}}Dark(){{if $handler.HandlerType}}){{end}})
{{ end }}
{{ end }}
{{ end }}
@@ -212,21 +255,26 @@ const docsTmpl = `---
title: zitadel/assets
---
{/*
Code generated by assets generator. DO NOT EDIT.
This file is checked in to support building docs without a Go environment.
*/}
## {{.Name}}
{{ range $service := .Services}}
{{ range $methodName, $method := .Methods}}
{{ range $method := .Methods}}
{{ range $handler := .Handlers}}
### {{$handler.Name}}{{$methodName}}()
### {{$handler.Name}}{{$method.Name}}()
> {{$handler.Name}}{{$methodName}}()
> {{$handler.Name}}{{$method.Name}}()
{{$handler.Method}}: {{$service.Prefix}}{{$method.Path}}{{$handler.PathSuffix}}
{{ if $method.HasDarkMode }}
### {{$handler.Name}}{{$methodName}}()
### {{$handler.Name}}{{$method.Name}}Dark()
> {{$handler.Name}}{{$methodName}}Dark()
> {{$handler.Name}}{{$method.Name}}Dark()
{{$handler.Method}}: {{$service.Prefix}}{{$method.Path}}/dark{{$handler.PathSuffix}}
{{ end }}