Compare commits

..
17 Commits
Author SHA1 Message Date
xixu-me 01c794e30f chore: release 1.0.0
Release / Verify and publish (push) Waiting to run
2026-03-27 10:51:14 +08:00
xixu-me b80f31616a fix(cli): correct skvlt command usage 2026-03-27 09:39:26 +08:00
xixu-me 74c3cd5f99 fix(manifest): add generated file header 2026-03-27 05:05:47 +08:00
xixu-me d40ba7fbe5 chore: add FUNDING.yml for sponsorship information 2026-03-27 03:35:23 +08:00
xixu-me 90db1e1621 chore: release 1.1.0 2026-03-27 03:29:29 +08:00
xixu-me ffbf63f1e2 ci: fix release workflow shell syntax 2026-03-27 03:20:35 +08:00
xixu-me 2fa9aa178f ci: tolerate npm version probe failures 2026-03-27 03:19:20 +08:00
xixu-me 9f5f737915 ci: make release workflow idempotent 2026-03-27 03:17:56 +08:00
xixu-me 241e6b2779 chore: release 1.0.0 2026-03-27 02:56:08 +08:00
xixu-me 46c07dfdf2 fix(docs): update Bun reference in README files to include hyperlink 2026-03-27 02:44:54 +08:00
xixu-me 05f4fd1b7d docs: refresh project docs and community templates 2026-03-27 02:42:37 +08:00
xixu-me 8c8315c181 feat(cli): improve restore progress and command guidance 2026-03-27 01:50:45 +08:00
xixu-me 29374db01f fix: restore formatting and README link emphasis 2026-03-27 01:30:59 +08:00
xixu-me 7fa8129296 feat(cli): polish help and output rendering 2026-03-27 01:22:44 +08:00
xixu-me 03ec9cde64 test(packaging): align readme install assertion 2026-03-25 22:31:53 +08:00
github-actions[bot] 80d66c3451 Merge pull request #1 from xixu-me/dependabot/github_actions/github-actions-20b45616f2
chore(deps): bump dependabot/fetch-metadata from 2.3.0 to 2.5.0 in the github-actions group
2026-03-25 14:25:26 +00:00
dependabot[bot] 976ccd42f5 chore(deps): bump dependabot/fetch-metadata in the github-actions group
Bumps the github-actions group with 1 update: [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata).


Updates `dependabot/fetch-metadata` from 2.3.0 to 2.5.0
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/d7267f607e9d3fb96fc2fbe83e0af444713e90b7...21025c705c08248db411dc16f3619e6b5f9ea21a)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-25 14:21:49 +00:00
7 changed files with 40 additions and 198 deletions

No files matched your search

+2 -2
View File
@@ -66,10 +66,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
with:
node-version: ${{ env.NODE_VERSION }}
+27 -188
View File
@@ -1,204 +1,43 @@
name: Dependabot Auto Merge
on:
check_suite:
types: [completed]
workflow_run:
workflows:
- "CI"
- "CodeQL"
- "Dependabot Updates"
- "Dependency Review"
- "Release"
pull_request:
branches:
- main
types:
- completed
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
cancel-in-progress: false
- opened
- reopened
- synchronize
- ready_for_review
permissions:
contents: write
pull-requests: write
checks: read
statuses: read
jobs:
merge:
name: Auto-merge Dependabot PRs
enable-auto-merge:
name: Approve and enable auto-merge
if: github.event.pull_request.user.login == 'dependabot[bot]' && github.event.pull_request.draft == false
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Merge Dependabot PRs when checks pass
uses: actions/github-script@v9
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
github-token: ${{ secrets.GITHUB_TOKEN }}
const successfulCheckConclusions = new Set(["success", "skipped", "neutral"]);
const successfulStatusStates = new Set(["success"]);
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
- name: Approve Dependabot pull request
continue-on-error: true
run: gh pr review --approve "$PR_URL"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
const latestBy = (items, keyOf, timeOf) => {
const latest = new Map();
for (const item of items) {
const key = keyOf(item);
const itemTime = new Date(timeOf(item) || 0).getTime();
const existing = latest.get(key);
const existingTime = existing ? new Date(timeOf(existing) || 0).getTime() : -1;
if (!existing || itemTime >= existingTime) {
latest.set(key, item);
}
}
return [...latest.values()];
};
const findCandidatePulls = async () => {
const pulls = await github.paginate(github.rest.pulls.list, {
owner,
repo,
state: "open",
per_page: 100,
});
return pulls.filter((pr) => pr.user?.login === "dependabot[bot]");
};
const getMergeablePullRequest = async (pull_number) => {
for (let attempt = 1; attempt <= 6; attempt += 1) {
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number });
if (pr.mergeable !== null) {
return pr;
}
core.info("PR #" + pull_number + " mergeability is still being computed; retry " + attempt + "/6.");
await wait(5000);
}
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number });
return pr;
};
const getSignalState = async (sha) => {
const checkRuns = await github.paginate(github.rest.checks.listForRef, {
owner,
repo,
ref: sha,
per_page: 100,
});
const statuses = await github.paginate(github.rest.repos.listCommitStatusesForRef, {
owner,
repo,
ref: sha,
per_page: 100,
});
const latestChecks = latestBy(
checkRuns.filter((run) => run.name !== "Dependabot Auto Merge"),
(run) => (run.app?.slug || "unknown") + ":" + run.name,
(run) => run.completed_at || run.started_at || run.created_at,
);
const latestStatuses = latestBy(statuses, (status) => status.context, (status) => status.updated_at || status.created_at);
const pendingChecks = latestChecks.filter((run) => run.status !== "completed");
const failedChecks = latestChecks.filter(
(run) => run.status === "completed" && !successfulCheckConclusions.has(String(run.conclusion || "").toLowerCase()),
);
const failedStatuses = latestStatuses.filter((status) => !successfulStatusStates.has(String(status.state || "").toLowerCase()));
return {
totalSignals: latestChecks.length + latestStatuses.length,
pendingChecks,
failedChecks,
failedStatuses,
};
};
const { data: repository } = await github.rest.repos.get({ owner, repo });
const mergeMethods = [];
if (repository.allow_merge_commit) mergeMethods.push("merge");
if (repository.allow_squash_merge) mergeMethods.push("squash");
if (repository.allow_rebase_merge) mergeMethods.push("rebase");
if (mergeMethods.length === 0) {
core.info("This repository has no enabled pull request merge methods.");
return;
}
const pulls = await findCandidatePulls();
if (pulls.length === 0) {
core.info("No open Dependabot PRs to evaluate.");
return;
}
for (const candidate of pulls) {
const pull_number = candidate.number;
const pr = await getMergeablePullRequest(pull_number);
if (pr.user?.login !== "dependabot[bot]") {
core.info("PR #" + pull_number + " is no longer a Dependabot PR.");
continue;
}
if (pr.state !== "open" || pr.draft) {
core.info("PR #" + pull_number + " is not an open, ready PR.");
continue;
}
if (pr.mergeable !== true) {
core.info("PR #" + pull_number + " is not currently mergeable.");
continue;
}
const signalState = await getSignalState(pr.head.sha);
if (signalState.totalSignals === 0) {
core.info("PR #" + pull_number + " has no checks or statuses yet; skipping.");
continue;
}
if (signalState.pendingChecks.length > 0) {
core.info("PR #" + pull_number + " still has pending checks: " + signalState.pendingChecks.map((run) => run.name).join(", ") + ".");
continue;
}
if (signalState.failedChecks.length > 0 || signalState.failedStatuses.length > 0) {
const failedChecks = signalState.failedChecks.map((run) => run.name + "=" + run.conclusion).join(", ");
const failedStatuses = signalState.failedStatuses.map((status) => status.context + "=" + status.state).join(", ");
core.info("PR #" + pull_number + " is not green. Checks: " + (failedChecks || "none") + ". Statuses: " + (failedStatuses || "none") + ".");
continue;
}
let merged = false;
let lastError = null;
for (const merge_method of mergeMethods) {
try {
await github.rest.pulls.merge({ owner, repo, pull_number, merge_method });
core.info("Merged Dependabot PR #" + pull_number + " with " + merge_method + ".");
merged = true;
break;
} catch (error) {
lastError = error;
if (error.status === 403 || error.status === 405 || error.status === 409) {
core.info("Cannot merge PR #" + pull_number + " with " + merge_method + ": " + error.message);
continue;
}
throw error;
}
}
if (!merged) {
core.info("PR #" + pull_number + " could not be merged: " + (lastError?.message || "unknown error") + ".");
continue;
}
if (pr.head.repo?.full_name === owner + "/" + repo) {
try {
await github.rest.git.deleteRef({ owner, repo, ref: "heads/" + pr.head.ref });
core.info("Deleted branch " + pr.head.ref + ".");
} catch (error) {
core.info("Could not delete branch " + pr.head.ref + ": " + error.message);
}
}
}
# Requires repository auto-merge to be enabled in GitHub settings.
- name: Enable auto-merge
run: gh pr merge --auto --merge "$PR_URL"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
+2 -2
View File
@@ -21,9 +21,9 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Review dependency changes
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48
with:
config-file: ./.github/dependency-review-config.yml
+2 -2
View File
@@ -41,10 +41,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: https://registry.npmjs.org
-1
View File
@@ -3,7 +3,6 @@
**_[汉语](./README.zh.md)_**
[![npm version](https://img.shields.io/npm/v/skvlt)](https://www.npmjs.com/package/skvlt)
[![npm downloads](https://img.shields.io/npm/dm/skvlt?label=downloads)](https://www.npmjs.com/package/skvlt)
[![CI](https://img.shields.io/github/actions/workflow/status/xixu-me/skills-vault/ci.yml?branch=main&label=ci)](https://github.com/xixu-me/skills-vault/actions/workflows/ci.yml)
[![Bun](https://img.shields.io/badge/Bun-%3E%3D1.3.11-f9f1e1)](https://bun.sh/)
[![License](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
-1
View File
@@ -3,7 +3,6 @@
**_[English](./README.md)_**
[![npm version](https://img.shields.io/npm/v/skvlt)](https://www.npmjs.com/package/skvlt)
[![npm downloads](https://img.shields.io/npm/dm/skvlt?label=downloads)](https://www.npmjs.com/package/skvlt)
[![CI](https://img.shields.io/github/actions/workflow/status/xixu-me/skills-vault/ci.yml?branch=main&label=ci)](https://github.com/xixu-me/skills-vault/actions/workflows/ci.yml)
[![Bun](https://img.shields.io/badge/Bun-%3E%3D1.3.11-f9f1e1)](https://bun.sh/)
[![License](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
+7 -2
View File
@@ -10,6 +10,11 @@
},
},
"packages": {
"prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="],
}
"prettier": [
"prettier@3.8.1",
"",
{ "bin": { "prettier": "bin/prettier.cjs" } },
"sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
],
},
}