Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cmd/server/openapi/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5278,6 +5278,9 @@ const docTemplate = `{
"trusted": {
"$ref": "#/definitions/model.TrustedConfiguration"
},
"user_id": {
"type": "integer"
},
"visibility": {
"$ref": "#/definitions/RepoVisibility"
}
Expand Down Expand Up @@ -5377,6 +5380,9 @@ const docTemplate = `{
"trusted": {
"$ref": "#/definitions/model.TrustedConfiguration"
},
"user_id": {
"type": "integer"
},
"visibility": {
"$ref": "#/definitions/RepoVisibility"
}
Expand Down
2 changes: 1 addition & 1 deletion server/model/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (mode ApprovalMode) Valid() bool {
// Repo represents a repository.
type Repo struct {
ID int64 `json:"id,omitempty" xorm:"pk autoincr 'id'"`
UserID int64 `json:"-" xorm:"INDEX 'user_id'"`
UserID int64 `json:"user_id" xorm:"INDEX 'user_id'"`
ForgeID int64 `json:"forge_id,omitempty" xorm:"UNIQUE(forge) forge_id"`
// ForgeRemoteID is the unique identifier for the repository on the forge.
ForgeRemoteID ForgeRemoteID `json:"forge_remote_id" xorm:"UNIQUE(forge) forge_remote_id"`
Expand Down
6 changes: 5 additions & 1 deletion web/src/assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -595,5 +595,9 @@
"exit_fullscreen": "Exit fullscreen",
"help_translating": "You can help translate Woodpecker into your language on {0}.",
"weblate": "our Weblate",
"disabled": "Disabled"
"disabled": "Disabled",
"current_repo_user": "Current repository user: {user_id}",
"set_as_repo_user": "Set yourself as repository user",
"user_associated_to_repo": "The user account associated to the repository will be used for API requests to the forge.",
"repo_user_changed": "You are now the owner of this repository"
}
4 changes: 4 additions & 0 deletions web/src/lib/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ export default class WoodpeckerClient extends ApiClient {
return this._post(`/api/repos/${repoId}/repair`);
}

async chownRepo(repoId: number): Promise<unknown> {
return this._post(`/api/repos/${repoId}/chown`);
}

async createPipeline(repoId: number, options: PipelineOptions): Promise<Pipeline | string> {
return this._post(`/api/repos/${repoId}/pipelines`, options) as Promise<Pipeline | string>;
}
Expand Down
3 changes: 3 additions & 0 deletions web/src/lib/api/types/repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export interface Repo {
// The id of the forge that the repository is on.
forge_id: number;

// The id of the user that owns the repository. Will be used for api requests to the forge.
user_id: number;

// The source control management being used.
// Currently, this is either 'git' or 'hg' (Mercurial).
scm: string;
Expand Down
23 changes: 23 additions & 0 deletions web/src/views/repo/settings/Actions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@
@click="activateRepo"
/>

<div v-if="user && repo.user_id !== user?.id">
<p>
<span>{{ $t('current_repo_user', { user_id: repo.user_id }) }}</span>
<span>{{ $t('user_associated_to_repo') }}</span>
</p>

<Button
class="my-1 mr-4"
color="blue"
start-icon="turn-off"
:is-loading="isChowningRepo"
:text="$t('set_as_repo_user')"
@click="chownRepo"
/>
</div>

<Button
class="my-1 mr-4"
color="red"
Expand All @@ -50,6 +66,7 @@ import Button from '~/components/atomic/Button.vue';
import Settings from '~/components/layout/Settings.vue';
import useApiClient from '~/compositions/useApiClient';
import { useAsyncAction } from '~/compositions/useAsyncAction';
import useAuthentication from '~/compositions/useAuthentication';
import { requiredInject } from '~/compositions/useInjectProvide';
import useNotifications from '~/compositions/useNotifications';
import { useWPTitle } from '~/compositions/useWPTitle';
Expand All @@ -58,6 +75,7 @@ const apiClient = useApiClient();
const router = useRouter();
const notifications = useNotifications();
const i18n = useI18n();
const { user } = useAuthentication();

const repo = requiredInject('repo');

Expand Down Expand Up @@ -89,6 +107,11 @@ const { doSubmit: deactivateRepo, isLoading: isDeactivatingRepo } = useAsyncActi
await router.replace({ name: 'repos' });
});

const { doSubmit: chownRepo, isLoading: isChowningRepo } = useAsyncAction(async () => {
await apiClient.chownRepo(repo.value.id);
notifications.notify({ title: i18n.t('repo_user_changed'), type: 'success' });
});

const isActive = computed(() => repo?.value.active);

useWPTitle(computed(() => [i18n.t('repo.settings.actions.actions'), repo.value.full_name]));
Expand Down