@backstage/plugin-scaffolder-backend 1.3.0-next.1 → 1.3.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/index.cjs.js +101 -19
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +24 -2
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
+
## 1.3.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ce0d8d7eb1: Fixed a bug in `publish:github` action that didn't permit to add users as collaborators.
|
|
8
|
+
This fix required changing the way parameters are passed to the action.
|
|
9
|
+
In order to add a team as collaborator, now you must use the `team` field instead of `username`.
|
|
10
|
+
In order to add a user as collaborator, you must use the `user` field.
|
|
11
|
+
|
|
12
|
+
It's still possible to use the field `username` but is deprecated in favor of `team`.
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
- id: publish
|
|
16
|
+
name: Publish
|
|
17
|
+
action: publish:github
|
|
18
|
+
input:
|
|
19
|
+
repoUrl: ...
|
|
20
|
+
collaborators:
|
|
21
|
+
- access: ...
|
|
22
|
+
team: my_team
|
|
23
|
+
- access: ...
|
|
24
|
+
user: my_username
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- 582003a059: - Added an optional `list` method on the `TaskBroker` and `TaskStore` interface to list tasks by an optional `userEntityRef`
|
|
28
|
+
- Implemented a `list` method on the `DatabaseTaskStore` class to list tasks by an optional `userEntityRef`
|
|
29
|
+
- Added a route under `/v2/tasks` to list tasks by a `userEntityRef` using the `createdBy` query parameter
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- Updated dependencies
|
|
34
|
+
- @backstage/backend-common@0.14.0-next.2
|
|
35
|
+
- @backstage/integration@1.2.1-next.2
|
|
36
|
+
- @backstage/plugin-catalog-backend@1.2.0-next.2
|
|
37
|
+
|
|
3
38
|
## 1.3.0-next.1
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -1862,22 +1862,36 @@ function createPublishGithubAction(options) {
|
|
|
1862
1862
|
},
|
|
1863
1863
|
collaborators: {
|
|
1864
1864
|
title: "Collaborators",
|
|
1865
|
-
description: "Provide additional users with permissions",
|
|
1865
|
+
description: "Provide additional users or teams with permissions",
|
|
1866
1866
|
type: "array",
|
|
1867
1867
|
items: {
|
|
1868
1868
|
type: "object",
|
|
1869
|
-
|
|
1869
|
+
additionalProperties: false,
|
|
1870
|
+
required: ["access"],
|
|
1870
1871
|
properties: {
|
|
1871
1872
|
access: {
|
|
1872
1873
|
type: "string",
|
|
1873
1874
|
description: "The type of access for the user",
|
|
1874
1875
|
enum: ["push", "pull", "admin", "maintain", "triage"]
|
|
1875
1876
|
},
|
|
1877
|
+
user: {
|
|
1878
|
+
type: "string",
|
|
1879
|
+
description: "The name of the user that will be added as a collaborator"
|
|
1880
|
+
},
|
|
1876
1881
|
username: {
|
|
1877
1882
|
type: "string",
|
|
1878
|
-
description: "
|
|
1883
|
+
description: "Deprecated. Use the `team` or `user` field instead."
|
|
1884
|
+
},
|
|
1885
|
+
team: {
|
|
1886
|
+
type: "string",
|
|
1887
|
+
description: "The name of the team that will be added as a collaborator"
|
|
1879
1888
|
}
|
|
1880
|
-
}
|
|
1889
|
+
},
|
|
1890
|
+
oneOf: [
|
|
1891
|
+
{ required: ["user"] },
|
|
1892
|
+
{ required: ["username"] },
|
|
1893
|
+
{ required: ["team"] }
|
|
1894
|
+
]
|
|
1881
1895
|
}
|
|
1882
1896
|
},
|
|
1883
1897
|
token: {
|
|
@@ -1990,21 +2004,37 @@ function createPublishGithubAction(options) {
|
|
|
1990
2004
|
});
|
|
1991
2005
|
}
|
|
1992
2006
|
if (collaborators) {
|
|
1993
|
-
for (const {
|
|
1994
|
-
access: permission,
|
|
1995
|
-
username: team_slug
|
|
1996
|
-
} of collaborators) {
|
|
2007
|
+
for (const collaborator of collaborators) {
|
|
1997
2008
|
try {
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2009
|
+
if ("user" in collaborator) {
|
|
2010
|
+
await client.rest.repos.addCollaborator({
|
|
2011
|
+
owner,
|
|
2012
|
+
repo,
|
|
2013
|
+
username: collaborator.user,
|
|
2014
|
+
permission: collaborator.access
|
|
2015
|
+
});
|
|
2016
|
+
} else if ("username" in collaborator) {
|
|
2017
|
+
ctx.logger.warn("The field `username` is deprecated in favor of `team` and will be removed in the future.");
|
|
2018
|
+
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
2019
|
+
org: owner,
|
|
2020
|
+
team_slug: collaborator.username,
|
|
2021
|
+
owner,
|
|
2022
|
+
repo,
|
|
2023
|
+
permission: collaborator.access
|
|
2024
|
+
});
|
|
2025
|
+
} else if ("team" in collaborator) {
|
|
2026
|
+
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
2027
|
+
org: owner,
|
|
2028
|
+
team_slug: collaborator.team,
|
|
2029
|
+
owner,
|
|
2030
|
+
repo,
|
|
2031
|
+
permission: collaborator.access
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2005
2034
|
} catch (e) {
|
|
2006
2035
|
errors.assertError(e);
|
|
2007
|
-
|
|
2036
|
+
const name = extractCollaboratorName(collaborator);
|
|
2037
|
+
ctx.logger.warn(`Skipping ${collaborator.access} access for ${name}, ${e.message}`);
|
|
2008
2038
|
}
|
|
2009
2039
|
}
|
|
2010
2040
|
}
|
|
@@ -2059,6 +2089,13 @@ function createPublishGithubAction(options) {
|
|
|
2059
2089
|
}
|
|
2060
2090
|
});
|
|
2061
2091
|
}
|
|
2092
|
+
function extractCollaboratorName(collaborator) {
|
|
2093
|
+
if ("username" in collaborator)
|
|
2094
|
+
return collaborator.username;
|
|
2095
|
+
if ("user" in collaborator)
|
|
2096
|
+
return collaborator.user;
|
|
2097
|
+
return collaborator.team;
|
|
2098
|
+
}
|
|
2062
2099
|
|
|
2063
2100
|
const DEFAULT_GLOB_PATTERNS = ["./**", "!.git"];
|
|
2064
2101
|
const isExecutable = (fileMode) => {
|
|
@@ -2834,6 +2871,12 @@ class TemplateActionRegistry {
|
|
|
2834
2871
|
}
|
|
2835
2872
|
|
|
2836
2873
|
const migrationsDir = backendCommon.resolvePackagePath("@backstage/plugin-scaffolder-backend", "migrations");
|
|
2874
|
+
const parseSqlDateToIsoString = (input) => {
|
|
2875
|
+
if (typeof input === "string") {
|
|
2876
|
+
return luxon.DateTime.fromSQL(input, { zone: "UTC" }).toISO();
|
|
2877
|
+
}
|
|
2878
|
+
return input;
|
|
2879
|
+
};
|
|
2837
2880
|
class DatabaseTaskStore {
|
|
2838
2881
|
static async create(options) {
|
|
2839
2882
|
await options.database.migrate.latest({
|
|
@@ -2844,6 +2887,27 @@ class DatabaseTaskStore {
|
|
|
2844
2887
|
constructor(options) {
|
|
2845
2888
|
this.db = options.database;
|
|
2846
2889
|
}
|
|
2890
|
+
async list(options) {
|
|
2891
|
+
const queryBuilder = this.db("tasks");
|
|
2892
|
+
if (options.createdBy) {
|
|
2893
|
+
queryBuilder.where({
|
|
2894
|
+
created_by: options.createdBy
|
|
2895
|
+
});
|
|
2896
|
+
}
|
|
2897
|
+
const results = await queryBuilder.orderBy("created_at", "desc").select();
|
|
2898
|
+
const tasks = results.map((result) => {
|
|
2899
|
+
var _a;
|
|
2900
|
+
return {
|
|
2901
|
+
id: result.id,
|
|
2902
|
+
spec: JSON.parse(result.spec),
|
|
2903
|
+
status: result.status,
|
|
2904
|
+
createdBy: (_a = result.created_by) != null ? _a : void 0,
|
|
2905
|
+
lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),
|
|
2906
|
+
createdAt: parseSqlDateToIsoString(result.created_at)
|
|
2907
|
+
};
|
|
2908
|
+
});
|
|
2909
|
+
return { tasks };
|
|
2910
|
+
}
|
|
2847
2911
|
async getTask(taskId) {
|
|
2848
2912
|
var _a;
|
|
2849
2913
|
const [result] = await this.db("tasks").where({ id: taskId }).select();
|
|
@@ -2857,8 +2921,8 @@ class DatabaseTaskStore {
|
|
|
2857
2921
|
id: result.id,
|
|
2858
2922
|
spec,
|
|
2859
2923
|
status: result.status,
|
|
2860
|
-
lastHeartbeatAt: result.last_heartbeat_at,
|
|
2861
|
-
createdAt: result.created_at,
|
|
2924
|
+
lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),
|
|
2925
|
+
createdAt: parseSqlDateToIsoString(result.created_at),
|
|
2862
2926
|
createdBy: (_a = result.created_by) != null ? _a : void 0,
|
|
2863
2927
|
secrets
|
|
2864
2928
|
};
|
|
@@ -2995,7 +3059,7 @@ class DatabaseTaskStore {
|
|
|
2995
3059
|
taskId,
|
|
2996
3060
|
body,
|
|
2997
3061
|
type: event.event_type,
|
|
2998
|
-
createdAt:
|
|
3062
|
+
createdAt: parseSqlDateToIsoString(event.created_at)
|
|
2999
3063
|
};
|
|
3000
3064
|
} catch (error) {
|
|
3001
3065
|
throw new Error(`Failed to parse event body from event taskId=${taskId} id=${event.id}, ${error}`);
|
|
@@ -3078,6 +3142,12 @@ class StorageTaskBroker {
|
|
|
3078
3142
|
this.logger = logger;
|
|
3079
3143
|
this.deferredDispatch = defer();
|
|
3080
3144
|
}
|
|
3145
|
+
async list(options) {
|
|
3146
|
+
if (!this.storage.list) {
|
|
3147
|
+
throw new Error("TaskStore does not implement the list method. Please implement the list method to be able to list tasks");
|
|
3148
|
+
}
|
|
3149
|
+
return await this.storage.list({ createdBy: options == null ? void 0 : options.createdBy });
|
|
3150
|
+
}
|
|
3081
3151
|
async claim() {
|
|
3082
3152
|
for (; ; ) {
|
|
3083
3153
|
const pendingTask = await this.storage.claimTask();
|
|
@@ -3682,6 +3752,18 @@ async function createRouter(options) {
|
|
|
3682
3752
|
}
|
|
3683
3753
|
});
|
|
3684
3754
|
res.status(201).json({ id: result.taskId });
|
|
3755
|
+
}).get("/v2/tasks", async (req, res) => {
|
|
3756
|
+
const [userEntityRef] = [req.query.createdBy].flat();
|
|
3757
|
+
if (typeof userEntityRef !== "string" && typeof userEntityRef !== "undefined") {
|
|
3758
|
+
throw new errors.InputError("createdBy query parameter must be a string");
|
|
3759
|
+
}
|
|
3760
|
+
if (!taskBroker.list) {
|
|
3761
|
+
throw new Error("TaskBroker does not support listing tasks, please implement the list method on the TaskBroker.");
|
|
3762
|
+
}
|
|
3763
|
+
const tasks = await taskBroker.list({
|
|
3764
|
+
createdBy: userEntityRef
|
|
3765
|
+
});
|
|
3766
|
+
res.status(200).json(tasks);
|
|
3685
3767
|
}).get("/v2/tasks/:taskId", async (req, res) => {
|
|
3686
3768
|
const { taskId } = req.params;
|
|
3687
3769
|
const task = await taskBroker.get(taskId);
|