Provisioning: Include Ref URLs in Job Status (#109464)

* Add URLs to Job spec

* Rename them as RefURLs

* Implement RefURLs for Github

* Add Ref URLs to Jobs

* Worker Test

* Create the branch in the staged writer

* Regenerate Git mock

* Format code

* Consolidate ResourceURLs and RefURLs into one

* Fix broken tests
This commit is contained in:
Roberto Jiménez Sánchez
2025-08-12 11:57:37 +02:00
committed by GitHub
parent 90dfc26b43
commit f2303a8ad9
30 changed files with 2157 additions and 218 deletions
@@ -829,6 +829,65 @@ func (_c *MockGithubRepository_ReadTree_Call) RunAndReturn(run func(context.Cont
return _c
}
// RefURLs provides a mock function with given fields: ctx, ref
func (_m *MockGithubRepository) RefURLs(ctx context.Context, ref string) (*v0alpha1.RepositoryURLs, error) {
ret := _m.Called(ctx, ref)
if len(ret) == 0 {
panic("no return value specified for RefURLs")
}
var r0 *v0alpha1.RepositoryURLs
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (*v0alpha1.RepositoryURLs, error)); ok {
return rf(ctx, ref)
}
if rf, ok := ret.Get(0).(func(context.Context, string) *v0alpha1.RepositoryURLs); ok {
r0 = rf(ctx, ref)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.RepositoryURLs)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, ref)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockGithubRepository_RefURLs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RefURLs'
type MockGithubRepository_RefURLs_Call struct {
*mock.Call
}
// RefURLs is a helper method to define mock.On call
// - ctx context.Context
// - ref string
func (_e *MockGithubRepository_Expecter) RefURLs(ctx interface{}, ref interface{}) *MockGithubRepository_RefURLs_Call {
return &MockGithubRepository_RefURLs_Call{Call: _e.mock.On("RefURLs", ctx, ref)}
}
func (_c *MockGithubRepository_RefURLs_Call) Run(run func(ctx context.Context, ref string)) *MockGithubRepository_RefURLs_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string))
})
return _c
}
func (_c *MockGithubRepository_RefURLs_Call) Return(_a0 *v0alpha1.RepositoryURLs, _a1 error) *MockGithubRepository_RefURLs_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockGithubRepository_RefURLs_Call) RunAndReturn(run func(context.Context, string) (*v0alpha1.RepositoryURLs, error)) *MockGithubRepository_RefURLs_Call {
_c.Call.Return(run)
return _c
}
// Repo provides a mock function with no fields
func (_m *MockGithubRepository) Repo() string {
ret := _m.Called()
@@ -875,23 +934,23 @@ func (_c *MockGithubRepository_Repo_Call) RunAndReturn(run func() string) *MockG
}
// ResourceURLs provides a mock function with given fields: ctx, file
func (_m *MockGithubRepository) ResourceURLs(ctx context.Context, file *repository.FileInfo) (*v0alpha1.ResourceURLs, error) {
func (_m *MockGithubRepository) ResourceURLs(ctx context.Context, file *repository.FileInfo) (*v0alpha1.RepositoryURLs, error) {
ret := _m.Called(ctx, file)
if len(ret) == 0 {
panic("no return value specified for ResourceURLs")
}
var r0 *v0alpha1.ResourceURLs
var r0 *v0alpha1.RepositoryURLs
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *repository.FileInfo) (*v0alpha1.ResourceURLs, error)); ok {
if rf, ok := ret.Get(0).(func(context.Context, *repository.FileInfo) (*v0alpha1.RepositoryURLs, error)); ok {
return rf(ctx, file)
}
if rf, ok := ret.Get(0).(func(context.Context, *repository.FileInfo) *v0alpha1.ResourceURLs); ok {
if rf, ok := ret.Get(0).(func(context.Context, *repository.FileInfo) *v0alpha1.RepositoryURLs); ok {
r0 = rf(ctx, file)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.ResourceURLs)
r0 = ret.Get(0).(*v0alpha1.RepositoryURLs)
}
}
@@ -923,12 +982,12 @@ func (_c *MockGithubRepository_ResourceURLs_Call) Run(run func(ctx context.Conte
return _c
}
func (_c *MockGithubRepository_ResourceURLs_Call) Return(_a0 *v0alpha1.ResourceURLs, _a1 error) *MockGithubRepository_ResourceURLs_Call {
func (_c *MockGithubRepository_ResourceURLs_Call) Return(_a0 *v0alpha1.RepositoryURLs, _a1 error) *MockGithubRepository_ResourceURLs_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockGithubRepository_ResourceURLs_Call) RunAndReturn(run func(context.Context, *repository.FileInfo) (*v0alpha1.ResourceURLs, error)) *MockGithubRepository_ResourceURLs_Call {
func (_c *MockGithubRepository_ResourceURLs_Call) RunAndReturn(run func(context.Context, *repository.FileInfo) (*v0alpha1.RepositoryURLs, error)) *MockGithubRepository_ResourceURLs_Call {
_c.Call.Return(run)
return _c
}
@@ -198,7 +198,7 @@ func (r *githubRepository) ListRefs(ctx context.Context) ([]provisioning.RefItem
}
// ResourceURLs implements RepositoryWithURLs.
func (r *githubRepository) ResourceURLs(ctx context.Context, file *repository.FileInfo) (*provisioning.ResourceURLs, error) {
func (r *githubRepository) ResourceURLs(ctx context.Context, file *repository.FileInfo) (*provisioning.RepositoryURLs, error) {
cfg := r.config.Spec.GitHub
if file.Path == "" || cfg == nil {
return nil, nil
@@ -209,7 +209,7 @@ func (r *githubRepository) ResourceURLs(ctx context.Context, file *repository.Fi
ref = cfg.Branch
}
urls := &provisioning.ResourceURLs{
urls := &provisioning.RepositoryURLs{
RepositoryURL: cfg.URL,
SourceURL: fmt.Sprintf("%s/blob/%s/%s", cfg.URL, ref, file.Path),
}
@@ -224,6 +224,25 @@ func (r *githubRepository) ResourceURLs(ctx context.Context, file *repository.Fi
return urls, nil
}
// RefURLs implements RepositoryWithURLs.
func (r *githubRepository) RefURLs(ctx context.Context, ref string) (*provisioning.RepositoryURLs, error) {
cfg := r.config.Spec.GitHub
if cfg == nil || ref == "" {
return nil, nil
}
urls := &provisioning.RepositoryURLs{
SourceURL: fmt.Sprintf("%s/tree/%s", cfg.URL, ref),
}
if ref != cfg.Branch {
urls.CompareURL = fmt.Sprintf("%s/compare/%s...%s", cfg.URL, cfg.Branch, ref)
urls.NewPullRequestURL = fmt.Sprintf("%s?quick_pull=1&labels=grafana", urls.CompareURL)
}
return urls, nil
}
func (r *githubRepository) OnCreate(_ context.Context) ([]map[string]interface{}, error) {
return nil, nil
}
@@ -688,7 +688,7 @@ func TestGitHubRepositoryResourceURLs(t *testing.T) {
name string
file *repository.FileInfo
config *provisioning.Repository
expectedURLs *provisioning.ResourceURLs
expectedURLs *provisioning.RepositoryURLs
expectedError error
}{
{
@@ -705,7 +705,7 @@ func TestGitHubRepositoryResourceURLs(t *testing.T) {
},
},
},
expectedURLs: &provisioning.ResourceURLs{
expectedURLs: &provisioning.RepositoryURLs{
RepositoryURL: "https://github.com/grafana/grafana",
SourceURL: "https://github.com/grafana/grafana/blob/feature-branch/dashboards/test.json",
CompareURL: "https://github.com/grafana/grafana/compare/main...feature-branch",
@@ -726,7 +726,7 @@ func TestGitHubRepositoryResourceURLs(t *testing.T) {
},
},
},
expectedURLs: &provisioning.ResourceURLs{
expectedURLs: &provisioning.RepositoryURLs{
RepositoryURL: "https://github.com/grafana/grafana",
SourceURL: "https://github.com/grafana/grafana/blob/main/dashboards/test.json",
},
@@ -783,6 +783,92 @@ func TestGitHubRepositoryResourceURLs(t *testing.T) {
}
}
func TestGitHubRepositoryRefURLs(t *testing.T) {
tests := []struct {
name string
ref string
config *provisioning.Repository
expectedURLs *provisioning.RepositoryURLs
expectedError error
}{
{
name: "ref different from branch",
ref: "feature-branch",
config: &provisioning.Repository{
Spec: provisioning.RepositorySpec{
GitHub: &provisioning.GitHubRepositoryConfig{
URL: "https://github.com/grafana/grafana",
Branch: "main",
},
},
},
expectedURLs: &provisioning.RepositoryURLs{
SourceURL: "https://github.com/grafana/grafana/tree/feature-branch",
CompareURL: "https://github.com/grafana/grafana/compare/main...feature-branch",
NewPullRequestURL: "https://github.com/grafana/grafana/compare/main...feature-branch?quick_pull=1&labels=grafana",
},
},
{
name: "ref same as branch",
ref: "main",
config: &provisioning.Repository{
Spec: provisioning.RepositorySpec{
GitHub: &provisioning.GitHubRepositoryConfig{
URL: "https://github.com/grafana/grafana",
Branch: "main",
},
},
},
expectedURLs: &provisioning.RepositoryURLs{
SourceURL: "https://github.com/grafana/grafana/tree/main",
},
},
{
name: "empty ref returns nil",
ref: "",
config: &provisioning.Repository{
Spec: provisioning.RepositorySpec{
GitHub: &provisioning.GitHubRepositoryConfig{
URL: "https://github.com/grafana/grafana",
Branch: "main",
},
},
},
expectedURLs: nil,
},
{
name: "nil github config returns nil",
ref: "feature-branch",
config: &provisioning.Repository{
Spec: provisioning.RepositorySpec{
GitHub: nil,
},
},
expectedURLs: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
repo := &githubRepository{
config: tt.config,
owner: "grafana",
repo: "grafana",
}
urls, err := repo.RefURLs(context.Background(), tt.ref)
if tt.expectedError != nil {
require.Error(t, err)
require.Equal(t, tt.expectedError.Error(), err.Error())
} else {
require.NoError(t, err)
require.Equal(t, tt.expectedURLs, urls)
}
})
}
}
// Test simple delegation functions
func TestGitHubRepositoryDelegation(t *testing.T) {
ctx := context.Background()