reposets 4.0.0 → 4.0.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/bin/reposets.js +8 -7
- package/cli/commands/credentials.js +2 -20
- package/cli/commands/doctor.js +12 -28
- package/cli/commands/init.js +2 -2
- package/cli/commands/nuke.js +1 -1
- package/cli/commands/sync.js +3 -3
- package/cli/commands/validate.js +1 -1
- package/index.js +1 -1
- package/package.json +16 -14
- package/services/ConfigFiles.js +9 -1
- package/store/SyncJournal.js +4 -3
- package/sync/SyncEngine.js +1 -1
- package/sync/phases/code-scanning.js +2 -2
- package/sync/phases/environments.js +1 -1
- package/sync/phases/index.js +1 -1
- package/sync/phases/rulesets.js +2 -2
- package/sync/phases/secrets.js +2 -2
- package/sync/phases/security.js +1 -1
- package/sync/phases/settings.js +4 -3
- package/sync/phases/variables.js +2 -2
- package/tsdoc-metadata.json +1 -1
package/bin/reposets.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Invocation } from "../services/Invocation.js";
|
|
3
2
|
import { CredentialsFilesLive } from "../services/ConfigFiles.js";
|
|
3
|
+
import { Invocation } from "../services/Invocation.js";
|
|
4
4
|
import { CACHE_OPTIONS, STORE_OPTIONS } from "../store/files.js";
|
|
5
5
|
import { SyncJournalLive } from "../store/SyncJournal.js";
|
|
6
6
|
import { credentialsCommand } from "../cli/commands/credentials.js";
|
|
7
7
|
import { doctorCommand } from "../cli/commands/doctor.js";
|
|
8
|
-
import { syncCommand } from "../cli/commands/sync.js";
|
|
9
8
|
import { driftCommand } from "../cli/commands/drift.js";
|
|
10
9
|
import { historyCommand } from "../cli/commands/history.js";
|
|
11
10
|
import { initCommand } from "../cli/commands/init.js";
|
|
12
11
|
import { listCommand } from "../cli/commands/list.js";
|
|
13
12
|
import { nukeCommand } from "../cli/commands/nuke.js";
|
|
13
|
+
import { syncCommand } from "../cli/commands/sync.js";
|
|
14
14
|
import { validateCommand } from "../cli/commands/validate.js";
|
|
15
15
|
import { ConfigFlag, ConfigLive } from "../cli/flags.js";
|
|
16
16
|
import { Effect, Layer, Predicate } from "effect";
|
|
17
17
|
import { App, AppCache, AppStore } from "@effected/app";
|
|
18
|
-
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
18
|
+
import { NodeCrypto, NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
19
19
|
import { CliAudience, CliRuntime, ConfigIssueRenderer, Fmt } from "@effected/cli";
|
|
20
20
|
import { Command } from "effect/cli";
|
|
21
21
|
|
|
@@ -31,7 +31,7 @@ import { Command } from "effect/cli";
|
|
|
31
31
|
* `0.0.0 (dev build)` from every build until the version was threaded down
|
|
32
32
|
* from here through {@link Invocation}.
|
|
33
33
|
*/
|
|
34
|
-
const VERSION = "4.0.
|
|
34
|
+
const VERSION = "4.0.2";
|
|
35
35
|
/**
|
|
36
36
|
* The application's directories: XDG resolution and the `reposets` namespace
|
|
37
37
|
* under it.
|
|
@@ -121,8 +121,9 @@ const cli = Command.make("reposets", {}, () => Effect.void).pipe(Command.withDes
|
|
|
121
121
|
credentialsCommand
|
|
122
122
|
]), Command.provide(ConfigLive), Command.provide(CredentialsFilesLive), Command.withGlobalFlags([ConfigFlag]), Command.withSharedFlags(CliAudience.flags()));
|
|
123
123
|
/**
|
|
124
|
-
* The platform: Node's services,
|
|
125
|
-
* the
|
|
124
|
+
* The platform: Node's services, `SecureRandom` (which `NodeServices` no longer
|
|
125
|
+
* carries; the journal mints run ids with it), the application's directories
|
|
126
|
+
* over them, and the invocation facts.
|
|
126
127
|
*
|
|
127
128
|
* @remarks
|
|
128
129
|
* `provideMerge` rather than `provide`, because commands require the platform
|
|
@@ -133,7 +134,7 @@ const cli = Command.make("reposets", {}, () => Effect.void).pipe(Command.withDes
|
|
|
133
134
|
* colour-aware help formatter itself, closer to the program, and one set here
|
|
134
135
|
* would be shadowed.
|
|
135
136
|
*/
|
|
136
|
-
const PlatformLive = Layer.mergeAll(DirsLive, InvocationLive).pipe(Layer.provideMerge(NodeServices.layer));
|
|
137
|
+
const PlatformLive = Layer.mergeAll(DirsLive, InvocationLive).pipe(Layer.provideMerge(Layer.mergeAll(NodeServices.layer, NodeCrypto.layerSecureRandom)));
|
|
137
138
|
/**
|
|
138
139
|
* Render a failure that escaped a command, one line at a time, to stderr.
|
|
139
140
|
*
|
|
@@ -96,24 +96,6 @@ const SECRET_IN_NAME = "That looks like a token, not a name. It was not stored."
|
|
|
96
96
|
/** What `--env` names, and what the prompt accepts for it: a shell variable identifier. */
|
|
97
97
|
const ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
98
98
|
/**
|
|
99
|
-
* Write credentials back to the file they were read from.
|
|
100
|
-
*
|
|
101
|
-
* @remarks
|
|
102
|
-
* `ConfigFileShape.save` resolves its own default path — the XDG one — rather
|
|
103
|
-
* than the path `discover` found. With a project-local
|
|
104
|
-
* `reposets.credentials.toml` present, that splits reads from writes: `create`
|
|
105
|
-
* lands in XDG while `list` keeps reading the local file, so a profile is
|
|
106
|
-
* created that the user cannot see and that sync will not use. Writing back to
|
|
107
|
-
* the discovered source keeps one file authoritative, and falls back to `save`
|
|
108
|
-
* only when there is genuinely nothing to update.
|
|
109
|
-
*/
|
|
110
|
-
const saveWhereRead = (file, value) => Effect.gen(function* () {
|
|
111
|
-
const existing = (yield* file.discover.pipe(Effect.orElseSucceed(() => [])))[0];
|
|
112
|
-
if (existing === void 0) return yield* file.save(value);
|
|
113
|
-
yield* file.write(value, existing.path);
|
|
114
|
-
return existing.path;
|
|
115
|
-
});
|
|
116
|
-
/**
|
|
117
99
|
* Refuse an invocation the user got wrong.
|
|
118
100
|
*
|
|
119
101
|
* @remarks
|
|
@@ -284,7 +266,7 @@ const createHandler = (input) => Effect.gen(function* () {
|
|
|
284
266
|
...actsAs,
|
|
285
267
|
github_token
|
|
286
268
|
};
|
|
287
|
-
const path = yield*
|
|
269
|
+
const path = yield* credentialsFile.save({ profiles: {
|
|
288
270
|
...existing.profiles,
|
|
289
271
|
[profile]: record
|
|
290
272
|
} });
|
|
@@ -378,7 +360,7 @@ const deleteHandler = (profile) => Effect.gen(function* () {
|
|
|
378
360
|
}), "Provide --profile <name>: the profile to delete."));
|
|
379
361
|
if (credentials.profiles[name] === void 0) return yield* refuse(`Profile '${name}' not found.`);
|
|
380
362
|
const { [name]: _removed, ...remaining } = credentials.profiles;
|
|
381
|
-
const path = yield*
|
|
363
|
+
const path = yield* credentialsFile.save({ profiles: remaining });
|
|
382
364
|
yield* CliMessage.success(`Deleted profile '${name}' from ${path}.`);
|
|
383
365
|
});
|
|
384
366
|
const deleteCommand = Command.make("delete", { profile: profileFlag }, ({ profile }) => deleteHandler(Option.getOrUndefined(profile))).pipe(Command.withDescription("Remove a credential profile"));
|
package/cli/commands/doctor.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { SettingsGroupSchema } from "../../schemas/config.js";
|
|
2
2
|
import { profileOwner } from "../../schemas/credentials.js";
|
|
3
|
-
import { Invocation } from "../../services/Invocation.js";
|
|
4
3
|
import { CREDENTIALS_FILENAME, ReposetsConfigFile, ReposetsCredentialsFile } from "../../services/ConfigFiles.js";
|
|
5
|
-
import { STORE_OPTIONS } from "../../store/files.js";
|
|
6
|
-
import { OP_SERVICE_ACCOUNT_TOKEN, OnePasswordClientLive } from "../../services/OnePasswordClient.js";
|
|
7
4
|
import { CredentialResolver, CredentialResolverLive } from "../../services/CredentialResolver.js";
|
|
5
|
+
import { Invocation } from "../../services/Invocation.js";
|
|
6
|
+
import { OP_SERVICE_ACCOUNT_TOKEN, OnePasswordClientLive } from "../../services/OnePasswordClient.js";
|
|
7
|
+
import { STORE_OPTIONS } from "../../store/files.js";
|
|
8
8
|
import { Config, Console, Effect, FileSystem, Layer, Option, Path, Predicate, Result } from "effect";
|
|
9
9
|
import { AppStore } from "@effected/app";
|
|
10
10
|
import { CliMessage, Doc, Fmt, SchemaIssueRenderer, Status } from "@effected/cli";
|
|
@@ -157,31 +157,15 @@ const REQUIRED_PERMISSIONS = [
|
|
|
157
157
|
"resolve team slugs (org-owned repos only)"
|
|
158
158
|
]
|
|
159
159
|
];
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
return matrix[a.length][b.length];
|
|
171
|
-
};
|
|
172
|
-
/** The nearest known key within edit distance 3, if any. */
|
|
173
|
-
const findClosestMatch = (key, known) => {
|
|
174
|
-
let best;
|
|
175
|
-
let bestDist = Number.POSITIVE_INFINITY;
|
|
176
|
-
for (const candidate of known) {
|
|
177
|
-
const dist = levenshtein(key, candidate);
|
|
178
|
-
if (dist < bestDist && dist <= 3) {
|
|
179
|
-
bestDist = dist;
|
|
180
|
-
best = candidate;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return best;
|
|
184
|
-
};
|
|
160
|
+
/**
|
|
161
|
+
* The nearest known key within edit distance 3, if any.
|
|
162
|
+
*
|
|
163
|
+
* @remarks
|
|
164
|
+
* Three edits, the threshold this check had before it moved onto the kit;
|
|
165
|
+
* `Fmt.suggest` defaults to two, `effect/cli`'s threshold. Ties keep the
|
|
166
|
+
* first known key, as before.
|
|
167
|
+
*/
|
|
168
|
+
const findClosestMatch = (key, known) => Fmt.suggest(key, known, { maxDistance: 3 })[0];
|
|
185
169
|
/**
|
|
186
170
|
* The credential resolver `doctor`'s live token check runs through.
|
|
187
171
|
*
|
package/cli/commands/init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Invocation } from "../../services/Invocation.js";
|
|
2
|
-
import { CONFIG_FILENAME, CREDENTIALS_FILENAME } from "../../services/ConfigFiles.js";
|
|
3
1
|
import { configSchemaHost, credentialsSchemaHost, schemaDirective } from "../../schemas/hosted.js";
|
|
2
|
+
import { CONFIG_FILENAME, CREDENTIALS_FILENAME } from "../../services/ConfigFiles.js";
|
|
3
|
+
import { Invocation } from "../../services/Invocation.js";
|
|
4
4
|
import { Effect, FileSystem, Option, Path } from "effect";
|
|
5
5
|
import { CliExit, CliMessage } from "@effected/cli";
|
|
6
6
|
import { Command, Flag } from "effect/cli";
|
package/cli/commands/nuke.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Invocation } from "../../services/Invocation.js";
|
|
2
1
|
import { CONFIG_FILENAME, CREDENTIALS_FILENAME } from "../../services/ConfigFiles.js";
|
|
2
|
+
import { Invocation } from "../../services/Invocation.js";
|
|
3
3
|
import { CACHE_OPTIONS, STORE_OPTIONS } from "../../store/files.js";
|
|
4
4
|
import { Effect, FileSystem, Path } from "effect";
|
|
5
5
|
import { AppCache, AppStore } from "@effected/app";
|
package/cli/commands/sync.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { danglingReferences } from "../../lib/config-refs.js";
|
|
1
2
|
import { ReposetsConfigFile, ReposetsCredentialsFile } from "../../services/ConfigFiles.js";
|
|
2
|
-
import { SyncJournal, SyncJournalLive } from "../../store/SyncJournal.js";
|
|
3
|
-
import { OnePasswordClientLive } from "../../services/OnePasswordClient.js";
|
|
4
3
|
import { CredentialResolver, CredentialResolverLive } from "../../services/CredentialResolver.js";
|
|
5
|
-
import {
|
|
4
|
+
import { OnePasswordClientLive } from "../../services/OnePasswordClient.js";
|
|
6
5
|
import { SyncLogger, SyncLoggerLive } from "../../services/SyncLogger.js";
|
|
7
6
|
import { AppliedStateLive } from "../../store/AppliedState.js";
|
|
8
7
|
import { RepoCacheLive } from "../../store/RepoCache.js";
|
|
8
|
+
import { SyncJournal, SyncJournalLive } from "../../store/SyncJournal.js";
|
|
9
9
|
import { PHASE_NAMES } from "../../sync/phase.js";
|
|
10
10
|
import { allPhases } from "../../sync/phases/index.js";
|
|
11
11
|
import { SyncEngine, SyncEngineLive } from "../../sync/SyncEngine.js";
|
package/cli/commands/validate.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ReposetsConfigFile, ReposetsCredentialsFile } from "../../services/ConfigFiles.js";
|
|
2
1
|
import { danglingReferences } from "../../lib/config-refs.js";
|
|
3
2
|
import { undefinedCredentialLabels } from "../../lib/credential-labels.js";
|
|
4
3
|
import { orgOnlyViolations } from "../../lib/org-only.js";
|
|
4
|
+
import { ReposetsConfigFile, ReposetsCredentialsFile } from "../../services/ConfigFiles.js";
|
|
5
5
|
import { Effect } from "effect";
|
|
6
6
|
import { CliExit, CliMessage, Doc, Status } from "@effected/cli";
|
|
7
7
|
import { Command } from "effect/cli";
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConfigSchema } from "./schemas/config.js";
|
|
2
|
-
import { Invocation } from "./services/Invocation.js";
|
|
3
2
|
import { CONFIG_FILENAME, ConfigFlagMissingConfig, ConfigFlagNotFound, ReposetsConfigFile, makeConfigFilesLive } from "./services/ConfigFiles.js";
|
|
3
|
+
import { Invocation } from "./services/Invocation.js";
|
|
4
4
|
|
|
5
5
|
export { CONFIG_FILENAME, ConfigFlagMissingConfig, ConfigFlagNotFound, ConfigSchema, Invocation, ReposetsConfigFile, makeConfigFilesLive };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reposets",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "CLI tool to sync GitHub repo settings, secrets and rulesets across personal repositories",
|
|
6
6
|
"keywords": [
|
|
@@ -48,20 +48,22 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@1password/sdk": "^0.5.0",
|
|
51
|
-
"@effect/platform-node": "
|
|
52
|
-
"@effected/app": "^0.
|
|
53
|
-
"@effected/cli": "^0.
|
|
54
|
-
"@effected/config-file": "^0.
|
|
55
|
-
"@effected/env": "^0.
|
|
56
|
-
"@effected/github": "^0.
|
|
57
|
-
"@effected/glob": "^0.
|
|
58
|
-
"@effected/
|
|
59
|
-
"@effected/
|
|
60
|
-
"@effected/
|
|
61
|
-
"@effected/
|
|
62
|
-
"@effected/
|
|
51
|
+
"@effect/platform-node": "~4.1.1",
|
|
52
|
+
"@effected/app": "^0.30.0",
|
|
53
|
+
"@effected/cli": "^0.25.0",
|
|
54
|
+
"@effected/config-file": "^0.23.0",
|
|
55
|
+
"@effected/env": "^0.9.0",
|
|
56
|
+
"@effected/github": "^0.27.0",
|
|
57
|
+
"@effected/glob": "^0.17.0",
|
|
58
|
+
"@effected/jsonc": "^0.22.0",
|
|
59
|
+
"@effected/schemastore": "^0.28.0",
|
|
60
|
+
"@effected/store": "^0.22.0",
|
|
61
|
+
"@effected/toml": "^0.18.0",
|
|
62
|
+
"@effected/walker": "^0.24.0",
|
|
63
|
+
"@effected/xdg": "^0.18.0",
|
|
64
|
+
"@effected/yaml": "^0.27.0",
|
|
63
65
|
"blakejs": "^1.2.1",
|
|
64
|
-
"effect": "
|
|
66
|
+
"effect": "~4.1.1",
|
|
65
67
|
"ink": "^8.0.0",
|
|
66
68
|
"react": "^19.3.1"
|
|
67
69
|
},
|
package/services/ConfigFiles.js
CHANGED
|
@@ -78,6 +78,13 @@ const STRICT_KEYS = {
|
|
|
78
78
|
* `upwardWalk` defaults to `process.cwd()` when given no `cwd`, which made
|
|
79
79
|
* config discovery the one reader of `process` below the entrypoint.
|
|
80
80
|
*
|
|
81
|
+
* **Writes go back to the file that was found.** `AppConfig` pins
|
|
82
|
+
* `saveTarget: "default"`, the XDG path, which would split reads from writes
|
|
83
|
+
* when a project-local `reposets.credentials.toml` exists: `credentials create`
|
|
84
|
+
* would land in XDG while `list` and `sync` keep reading the local file.
|
|
85
|
+
* `"source"` writes to the highest-priority file the chain found, and to XDG
|
|
86
|
+
* only when there is none.
|
|
87
|
+
*
|
|
81
88
|
* @public
|
|
82
89
|
*/
|
|
83
90
|
const CredentialsFilesLive = Layer.unwrap(Effect.map(Invocation, ({ cwd }) => AppConfig.layer(ReposetsCredentialsFile, {
|
|
@@ -88,7 +95,8 @@ const CredentialsFilesLive = Layer.unwrap(Effect.map(Invocation, ({ cwd }) => Ap
|
|
|
88
95
|
filename: CREDENTIALS_FILENAME,
|
|
89
96
|
cwd
|
|
90
97
|
})],
|
|
91
|
-
parseOptions: STRICT_KEYS
|
|
98
|
+
parseOptions: STRICT_KEYS,
|
|
99
|
+
saveTarget: "source"
|
|
92
100
|
})));
|
|
93
101
|
/**
|
|
94
102
|
* Raised when `--config` names a path that does not exist.
|
package/store/SyncJournal.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Context,
|
|
1
|
+
import { Context, DateTime, Effect, Layer } from "effect";
|
|
2
2
|
import { Store } from "@effected/store";
|
|
3
|
+
import { SecureRandom } from "effect/crypto";
|
|
3
4
|
|
|
4
5
|
// src/store/SyncJournal.ts
|
|
5
6
|
/**
|
|
@@ -15,11 +16,11 @@ import { Store } from "@effected/store";
|
|
|
15
16
|
*/
|
|
16
17
|
var SyncJournal = class extends Context.Service()("reposets/SyncJournal", { make: Effect.gen(function* () {
|
|
17
18
|
const store = yield* Store;
|
|
18
|
-
const
|
|
19
|
+
const random = yield* SecureRandom.SecureRandom;
|
|
19
20
|
const sql = store.client;
|
|
20
21
|
return {
|
|
21
22
|
startRun: (options) => Effect.gen(function* () {
|
|
22
|
-
const id = yield*
|
|
23
|
+
const id = yield* random.uuidV7();
|
|
23
24
|
const startedAt = yield* DateTime.now;
|
|
24
25
|
yield* sql`
|
|
25
26
|
INSERT INTO sync_run (id, started_at, group_name, dry_run)
|
package/sync/SyncEngine.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { profileOwner } from "../schemas/credentials.js";
|
|
2
|
-
import { SyncJournal } from "../store/SyncJournal.js";
|
|
3
2
|
import { CredentialResolver } from "../services/CredentialResolver.js";
|
|
4
3
|
import { SyncLogger } from "../services/SyncLogger.js";
|
|
5
4
|
import { RepoCache } from "../store/RepoCache.js";
|
|
5
|
+
import { SyncJournal } from "../store/SyncJournal.js";
|
|
6
6
|
import { emptyResult, mergeResults, selectPhases } from "./phase.js";
|
|
7
7
|
import { Context, Effect, Layer } from "effect";
|
|
8
8
|
import { GitHubRepository, Repo, RepoRef } from "@effected/github";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { fingerprint } from "../../lib/fingerprint.js";
|
|
1
2
|
import { SyncLogger } from "../../services/SyncLogger.js";
|
|
2
3
|
import { AppliedState, lookup } from "../../store/AppliedState.js";
|
|
3
4
|
import { RepoCache } from "../../store/RepoCache.js";
|
|
4
|
-
import { read } from "./resource.js";
|
|
5
|
-
import { fingerprint } from "../../lib/fingerprint.js";
|
|
6
5
|
import { decide, isDrift, needsApply } from "../decide.js";
|
|
6
|
+
import { read } from "./resource.js";
|
|
7
7
|
import { Effect, Option } from "effect";
|
|
8
8
|
import { Fmt } from "@effected/cli";
|
|
9
9
|
import { CodeScanning, WorkflowDispatch } from "@effected/github";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { fingerprint } from "../../lib/fingerprint.js";
|
|
1
2
|
import { SyncLogger } from "../../services/SyncLogger.js";
|
|
2
3
|
import { AppliedState, lookup } from "../../store/AppliedState.js";
|
|
3
|
-
import { fingerprint } from "../../lib/fingerprint.js";
|
|
4
4
|
import { decide, isDrift, needsApply } from "../decide.js";
|
|
5
5
|
import { Effect, Option } from "effect";
|
|
6
6
|
import { Fmt } from "@effected/cli";
|
package/sync/phases/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { capture, declaredNames, resolveGroups } from "./resource.js";
|
|
2
1
|
import { cleanupPhase } from "./cleanup.js";
|
|
3
2
|
import { codeScanningPhase } from "./code-scanning.js";
|
|
4
3
|
import { environmentsPhase } from "./environments.js";
|
|
@@ -7,6 +6,7 @@ import { secretsPhase } from "./secrets.js";
|
|
|
7
6
|
import { securityPhase } from "./security.js";
|
|
8
7
|
import { settingsPhase } from "./settings.js";
|
|
9
8
|
import { variablesPhase } from "./variables.js";
|
|
9
|
+
import { capture, declaredNames, resolveGroups } from "./resource.js";
|
|
10
10
|
import { Effect } from "effect";
|
|
11
11
|
|
|
12
12
|
// src/sync/phases/index.ts
|
package/sync/phases/rulesets.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { fingerprint } from "../../lib/fingerprint.js";
|
|
1
2
|
import { buildRulesetPayload } from "../../schemas/ruleset.js";
|
|
2
3
|
import { SyncLogger } from "../../services/SyncLogger.js";
|
|
3
4
|
import { AppliedState, lookup } from "../../store/AppliedState.js";
|
|
4
5
|
import { RepoCache } from "../../store/RepoCache.js";
|
|
5
|
-
import { capture, read } from "./resource.js";
|
|
6
|
-
import { fingerprint } from "../../lib/fingerprint.js";
|
|
7
6
|
import { decide, isDrift, needsApply } from "../decide.js";
|
|
7
|
+
import { capture, read } from "./resource.js";
|
|
8
8
|
import { Effect, Option, Redacted } from "effect";
|
|
9
9
|
import { Ruleset } from "@effected/github";
|
|
10
10
|
|
package/sync/phases/secrets.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { fingerprint } from "../../lib/fingerprint.js";
|
|
1
2
|
import { SyncLogger } from "../../services/SyncLogger.js";
|
|
2
3
|
import { AppliedState, lookup } from "../../store/AppliedState.js";
|
|
3
|
-
import { capture, resolveGroups } from "./resource.js";
|
|
4
|
-
import { fingerprint } from "../../lib/fingerprint.js";
|
|
5
4
|
import { decide, isDrift, needsApply } from "../decide.js";
|
|
5
|
+
import { capture, resolveGroups } from "./resource.js";
|
|
6
6
|
import { Effect, FileSystem, Option, Path, Redacted } from "effect";
|
|
7
7
|
import { RepositorySecret } from "@effected/github";
|
|
8
8
|
|
package/sync/phases/security.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { fingerprint } from "../../lib/fingerprint.js";
|
|
1
2
|
import { SyncLogger } from "../../services/SyncLogger.js";
|
|
2
3
|
import { AppliedState, lookup } from "../../store/AppliedState.js";
|
|
3
|
-
import { fingerprint } from "../../lib/fingerprint.js";
|
|
4
4
|
import { decide, isDrift, needsApply } from "../decide.js";
|
|
5
5
|
import { Effect, Option } from "effect";
|
|
6
6
|
import { Fmt } from "@effected/cli";
|
package/sync/phases/settings.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { fingerprint } from "../../lib/fingerprint.js";
|
|
1
2
|
import { SyncLogger } from "../../services/SyncLogger.js";
|
|
2
3
|
import { AppliedState, lookup } from "../../store/AppliedState.js";
|
|
3
4
|
import { RepoCache } from "../../store/RepoCache.js";
|
|
4
|
-
import { read } from "./resource.js";
|
|
5
|
-
import { fingerprint } from "../../lib/fingerprint.js";
|
|
6
5
|
import { decide, isDrift, needsApply } from "../decide.js";
|
|
6
|
+
import { read } from "./resource.js";
|
|
7
7
|
import { Effect, Option } from "effect";
|
|
8
8
|
import { GitHubRepository, Ruleset } from "@effected/github";
|
|
9
9
|
|
|
@@ -237,7 +237,7 @@ const settingsPhase = Effect.gen(function* () {
|
|
|
237
237
|
};
|
|
238
238
|
let sent;
|
|
239
239
|
if (!ctx.dryRun) {
|
|
240
|
-
const outcome = yield* read(settingsClient.applySettings(desired));
|
|
240
|
+
const outcome = yield* read(settingsClient.applySettings(desired, { unknownKeys: "send" }));
|
|
241
241
|
if ("failed" in outcome) return {
|
|
242
242
|
changes: [],
|
|
243
243
|
errors: [...errors, {
|
|
@@ -245,6 +245,7 @@ const settingsPhase = Effect.gen(function* () {
|
|
|
245
245
|
message: outcome.failed
|
|
246
246
|
}]
|
|
247
247
|
};
|
|
248
|
+
for (const key of outcome.value.unverified) yield* logger.syncOperation("apply", "setting", key, "(unconfirmed: GitHub does not describe this field)");
|
|
248
249
|
sent = [...outcome.value.rest, ...outcome.value.graphql];
|
|
249
250
|
yield* applied.record({
|
|
250
251
|
repo: ctx.slug,
|
package/sync/phases/variables.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { fingerprint } from "../../lib/fingerprint.js";
|
|
1
2
|
import { SyncLogger } from "../../services/SyncLogger.js";
|
|
2
3
|
import { AppliedState, lookup } from "../../store/AppliedState.js";
|
|
3
|
-
import { capture, resolveGroups } from "./resource.js";
|
|
4
|
-
import { fingerprint } from "../../lib/fingerprint.js";
|
|
5
4
|
import { decide, isDrift, needsApply } from "../decide.js";
|
|
5
|
+
import { capture, resolveGroups } from "./resource.js";
|
|
6
6
|
import { Effect, FileSystem, Option, Path, Redacted } from "effect";
|
|
7
7
|
import { RepositoryVariable } from "@effected/github";
|
|
8
8
|
|