diff --git a/server/api/build.go b/server/api/build.go index 88973946f..39376af49 100644 --- a/server/api/build.go +++ b/server/api/build.go @@ -180,6 +180,30 @@ func GetProcLogs(c *gin.Context) { } } +func GetBuildConfig(c *gin.Context) { + _store := store.FromContext(c) + repo := session.Repo(c) + num, err := strconv.ParseInt(c.Param("number"), 10, 64) + if err != nil { + _ = c.AbortWithError(http.StatusBadRequest, err) + return + } + + build, err := _store.GetBuildNumber(repo, num) + if err != nil { + _ = c.AbortWithError(http.StatusInternalServerError, err) + return + } + + configs, err := _store.ConfigsForBuild(build.ID) + if err != nil { + c.String(http.StatusInternalServerError, err.Error()) + return + } + + c.JSON(http.StatusOK, configs) +} + // DeleteBuild cancels a build func DeleteBuild(c *gin.Context) { _store := store.FromContext(c) diff --git a/server/router/api.go b/server/router/api.go index e88c0a551..a41500cfe 100644 --- a/server/router/api.go +++ b/server/router/api.go @@ -61,6 +61,7 @@ func apiRoutes(e *gin.Engine) { repo.GET("/builds", api.GetBuilds) repo.GET("/builds/:number", api.GetBuild) + repo.GET("/builds/:number/config", api.GetBuildConfig) // requires push permissions repo.POST("/builds/:number", session.MustPush, api.PostBuild) diff --git a/web/src/lib/api/index.ts b/web/src/lib/api/index.ts index 26eb7d9e2..42b0e3c6a 100644 --- a/web/src/lib/api/index.ts +++ b/web/src/lib/api/index.ts @@ -1,5 +1,16 @@ import ApiClient, { encodeQueryString } from './client'; -import { Build, BuildFeed, BuildLog, BuildProc, Registry, Repo, RepoPermissions, RepoSettings, Secret } from './types'; +import { + Build, + BuildConfig, + BuildFeed, + BuildLog, + BuildProc, + Registry, + Repo, + RepoPermissions, + RepoSettings, + Secret, +} from './types'; type RepoListOptions = { all?: boolean; @@ -49,6 +60,10 @@ export default class WoodpeckerClient extends ApiClient { return this._get(`/api/repos/${owner}/${repo}/builds/${number}`) as Promise; } + getBuildConfig(owner: string, repo: string, number: number): Promise { + return this._get(`/api/repos/${owner}/${repo}/builds/${number}/config`) as Promise; + } + getBuildFeed(opts?: Record): Promise { const query = encodeQueryString(opts); return this._get(`/api/user/feed?${query}`) as Promise; diff --git a/web/src/lib/api/types/buildConfig.ts b/web/src/lib/api/types/buildConfig.ts new file mode 100644 index 000000000..496caba79 --- /dev/null +++ b/web/src/lib/api/types/buildConfig.ts @@ -0,0 +1,6 @@ +// A config for a build. +export type BuildConfig = { + hash: string; + name: string; + data: string; +}; diff --git a/web/src/lib/api/types/index.ts b/web/src/lib/api/types/index.ts index 54347095e..231da28fd 100644 --- a/web/src/lib/api/types/index.ts +++ b/web/src/lib/api/types/index.ts @@ -1,4 +1,5 @@ export * from './build'; +export * from './buildConfig'; export * from './registry'; export * from './repo'; export * from './secret'; diff --git a/web/src/router.ts b/web/src/router.ts index d8889e16c..cf866b64c 100644 --- a/web/src/router.ts +++ b/web/src/router.ts @@ -58,6 +58,12 @@ const routes: RouteRecordRaw[] = [ component: (): Component => import('~/views/repo/build/Build.vue'), props: true, }, + { + path: 'config', + name: 'repo-build-config', + component: (): Component => import('~/views/repo/build/BuildConfig.vue'), + props: true, + }, ], }, { diff --git a/web/src/views/repo/build/BuildConfig.vue b/web/src/views/repo/build/BuildConfig.vue new file mode 100644 index 000000000..874f7cbea --- /dev/null +++ b/web/src/views/repo/build/BuildConfig.vue @@ -0,0 +1,58 @@ + + + diff --git a/web/src/views/repo/build/BuildWrapper.vue b/web/src/views/repo/build/BuildWrapper.vue index 17833cb66..4e808997e 100644 --- a/web/src/views/repo/build/BuildWrapper.vue +++ b/web/src/views/repo/build/BuildWrapper.vue @@ -31,6 +31,7 @@
+
@@ -63,7 +64,7 @@ import { toRef, watch, } from 'vue'; -import { useRouter } from 'vue-router'; +import { useRoute, useRouter } from 'vue-router'; import Button from '~/components/atomic/Button.vue'; import IconButton from '~/components/atomic/IconButton.vue'; @@ -122,6 +123,7 @@ export default defineComponent({ setup(props) { const apiClient = useApiClient(); + const route = useRoute(); const router = useRouter(); const notifications = useNotifications(); const favicon = useFavicon(); @@ -191,12 +193,20 @@ export default defineComponent({ const activeTab = computed({ get() { + if (route.name === 'repo-build-config') { + return 'config'; + } + return 'tasks'; }, set(tab: string) { if (tab === 'tasks') { router.replace({ name: 'repo-build' }); } + + if (tab === 'config') { + router.replace({ name: 'repo-build-config' }); + } }, });