Compare commits

27 Commits
Author SHA1 Message Date
xixu-me 0ceebd00be fix(actions): avoid status event fan-out 2026-08-18 11:29:55 +08:00
xixu-me 8190a0e1aa fix(actions): retry Dependabot merge after checks 2026-08-18 11:25:17 +08:00
github-actions[bot] b36c006b93 Merge pull request #14 from xixu-me/dependabot-github_actions-actions-setup-go-7
Bump actions/setup-go from 6 to 7
2026-08-14 10:19:37 +00:00
xixu-me 8498a23468 fix(ci): evaluate all Dependabot pull requests 2026-08-14 18:15:02 +08:00
dependabot[bot] de534f46a4 Bump actions/setup-go from 6 to 7
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6 to 7.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-18 09:48:25 +00:00
xixu-me b90c194fa4 ci: follow upstream Go version 2026-07-18 17:46:29 +08:00
xixu-me 3d066cc836 ci: trigger Dependabot auto-merge from workflow runs 2026-07-03 23:33:29 +08:00
xixu-me 70a74b4df4 ci: tolerate protected Dependabot workflow updates 2026-07-03 23:13:40 +08:00
github-actions[bot] 5b89c174b8 Merge pull request #13 from xixu-me/dependabot-github_actions-actions-checkout-7
Bump actions/checkout from 6 to 7
2026-07-03 15:08:50 +00:00
xixu-me bc0fc1f997 ci: add Dependabot auto merge workflow 2026-07-03 23:02:53 +08:00
dependabot[bot] d029d71080 Bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-19 03:03:27 +00:00
xixu-me 7a3dde2c7d fix: address code scanning alerts 2026-06-14 20:01:54 +08:00
xixu-me fcc8e10fa6 Merge pull request #12 from xixu-me/dependabot-github_actions-softprops-action-gh-release-3
Bump softprops/action-gh-release from 2 to 3
2026-04-13 12:03:28 +08:00
dependabot[bot] 3036caf847 Bump softprops/action-gh-release from 2 to 3
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 03:11:03 +00:00
xixu-me d71f35bedd ci: avoid false positives in upstream response checks 2026-04-02 19:58:18 +08:00
xixu-me 6d660d9399 ci: harden remote ruleset downloads 2026-04-02 16:44:36 +08:00
xixu-me 750f3dce95 Retry CDN purge requests and warn on failure 2026-03-17 14:20:27 +08:00
xixu-me a87baf48d1 Merge pull request #10 from xixu-me/dependabot-github_actions-actions-download-artifact-8
Bump actions/download-artifact from 7 to 8
2026-02-27 14:31:30 +08:00
xixu-me a9df20e0bb Merge pull request #11 from xixu-me/dependabot-github_actions-actions-upload-artifact-7
Bump actions/upload-artifact from 6 to 7
2026-02-27 14:31:02 +08:00
dependabot[bot] 5c030cc3c4 Bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 03:05:04 +00:00
dependabot[bot] fca1ca44cd Bump actions/download-artifact from 7 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 03:04:59 +00:00
xixu-me 3517d9a9b9 Merge pull request #9 from xixu-me/dependabot-github_actions-actions-download-artifact-7
Bump actions/download-artifact from 6 to 7
2025-12-15 11:52:45 +08:00
xixu-me 5ef0ff9d76 Merge pull request #8 from xixu-me/dependabot-github_actions-actions-upload-artifact-6
Bump actions/upload-artifact from 5 to 6
2025-12-15 11:52:33 +08:00
dependabot[bot] 987ae3095d Bump actions/download-artifact from 6 to 7
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 03:12:13 +00:00
dependabot[bot] b9334b1bf7 Bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 03:12:10 +00:00
xixu-me 426c5bcce7 Merge pull request #7 from xixu-me/dependabot-github_actions-actions-checkout-6
Bump actions/checkout from 5 to 6
2025-11-21 13:09:11 +08:00
dependabot[bot] 91b09f8fb5 Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 03:11:55 +00:00
2 changed files with 334 additions and 33 deletions

No files matched your search

+132 -33
View File
@@ -5,6 +5,9 @@ on:
schedule: schedule:
- cron: "20 2,6,10,14,18,22 * * *" - cron: "20 2,6,10,14,18,22 * * *"
permissions:
contents: write
jobs: jobs:
build-and-publish-universal-rulesets: build-and-publish-universal-rulesets:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -25,32 +28,32 @@ jobs:
shell: bash shell: bash
- name: Checkout repositories - name: Checkout repositories
uses: actions/checkout@v5 uses: actions/checkout@v7
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: Loyalsoldier/domain-list-custom repository: Loyalsoldier/domain-list-custom
path: custom path: custom
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: v2fly/domain-list-community repository: v2fly/domain-list-community
path: community path: community
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: xixu-me/Dandified-DLC repository: xixu-me/Dandified-DLC
path: dnf path: dnf
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: MetaCubeX/meta-rules-converter repository: MetaCubeX/meta-rules-converter
path: converter path: converter
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: cokebar/gfwlist2dnsmasq repository: cokebar/gfwlist2dnsmasq
path: gfwlist2dnsmasq path: gfwlist2dnsmasq
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v6 uses: actions/setup-go@v7
with: with:
go-version: "1.22" go-version-file: ./custom/go.mod
cache-dependency-path: ./custom/go.sum cache-dependency-path: ./custom/go.sum
- name: Generate and process domain lists - name: Generate and process domain lists
@@ -117,17 +120,54 @@ jobs:
env: env:
SED: sed '/^\s*#/d' | sed 's/DOMAIN,//g' | sed 's/DOMAIN-SUFFIX,//g' | sed 's/DOMAIN-KEYWORD,/keyword:/g' SED: sed '/^\s*#/d' | sed 's/DOMAIN,//g' | sed 's/DOMAIN-SUFFIX,//g' | sed 's/DOMAIN-KEYWORD,/keyword:/g'
run: | run: |
curl_retry() {
curl --fail --show-error --silent --location --retry 3 --retry-delay 2 --retry-all-errors "$@"
}
response_looks_invalid() {
head -n 5 "$1" | grep -Eiq '^(429([[:space:]:]|$)|<!DOCTYPE html|<html)|Too Many Requests'
}
fetch_plain_list() {
local url="$1"
local dest="$2"
local tmp
tmp=$(mktemp)
curl_retry "$url" -o "$tmp"
if response_looks_invalid "$tmp"; then
echo "::error::Unexpected response while fetching ${url}"
head -n 5 "$tmp"
return 1
fi
mv "$tmp" "$dest"
}
fetch_transformed_list() {
local url="$1"
local dest="$2"
local tmp
tmp=$(mktemp)
curl_retry "$url" -o "$tmp"
if response_looks_invalid "$tmp"; then
echo "::error::Unexpected response while fetching ${url}"
head -n 5 "$tmp"
return 1
fi
cat "$tmp" | ${{ env.SED }} > "$dest"
rm -f "$tmp"
}
# Merge SteamCN list # Merge SteamCN list
curl -sSL https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/SteamCN/SteamCN.list | ${{ env.SED }} > steamcn.txt fetch_transformed_list https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/SteamCN/SteamCN.list steamcn.txt
while read line; do grep -q "$line @cn" ./community/data/steam || sed -i "/$line/ s/$/ @cn/" ./community/data/steam; done < steamcn.txt while read line; do grep -q "$line @cn" ./community/data/steam || sed -i "/$line/ s/$/ @cn/" ./community/data/steam; done < steamcn.txt
# Merge other lists # Merge other lists
curl -sSL https://raw.githubusercontent.com/xishang0128/rules/main/biliintl.list > ./community/data/biliintl fetch_plain_list https://raw.githubusercontent.com/xishang0128/rules/main/biliintl.list ./community/data/biliintl
curl -sSL https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/OneDrive/OneDrive.list | ${{ env.SED }} > ./community/data/onedrive fetch_transformed_list https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/OneDrive/OneDrive.list ./community/data/onedrive
echo "sharepoint.cn" >> ./community/data/onedrive echo "sharepoint.cn" >> ./community/data/onedrive
curl -sSL https://raw.githubusercontent.com/xishang0128/rules/main/sharepoint.list > ./community/data/sharepoint fetch_plain_list https://raw.githubusercontent.com/xishang0128/rules/main/sharepoint.list ./community/data/sharepoint
curl -sSL https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/PrivateTracker/PrivateTracker.list | ${{ env.SED }} > ./community/data/tracker fetch_transformed_list https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/PrivateTracker/PrivateTracker.list ./community/data/tracker
curl -sSL https://raw.githubusercontent.com/XIU2/TrackersListCollection/refs/heads/master/all.txt | grep -i "\.[A-Z]" | grep -v tracker | sed 's/^.*\/\///g' | sed 's/:.*\/.*//g' >> ./community/data/tracker curl_retry https://raw.githubusercontent.com/XIU2/TrackersListCollection/refs/heads/master/all.txt | grep -i "\.[A-Z]" | grep -v tracker | sed 's/^.*\/\///g' | sed 's/:.*\/.*//g' >> ./community/data/tracker
curl -sSL https://github.com/blackmatrix7/ios_rule_script/raw/master/rule/Clash/BlockHttpDNS/BlockHttpDNS.list | ${{ env.SED }} > ./community/data/httpdns fetch_transformed_list https://github.com/blackmatrix7/ios_rule_script/raw/master/rule/Clash/BlockHttpDNS/BlockHttpDNS.list ./community/data/httpdns
- name: Supplement lists - name: Supplement lists
run: | run: |
@@ -137,6 +177,13 @@ jobs:
run: | run: |
cd custom cd custom
echo ipleak.net >> ../community/data/geolocation-\!cn && echo browserleaks.org >> ../community/data/geolocation-\!cn echo ipleak.net >> ../community/data/geolocation-\!cn && echo browserleaks.org >> ../community/data/geolocation-\!cn
for file in ../community/data/*; do
if head -n 5 "$file" | grep -Eiq '^(429([[:space:]:]|$)|<!DOCTYPE html|<html)|Too Many Requests'; then
echo "::error file=${file}::Unexpected upstream response detected in ruleset input"
head -n 5 "$file"
exit 1
fi
done
go run ./ --datapath=../community/data go run ./ --datapath=../community/data
cd ../converter cd ../converter
mkdir -p ../converted mkdir -p ../converted
@@ -172,7 +219,7 @@ jobs:
rm to-be-merged/cn.yaml to-be-merged/geolocation-!cn.yaml to-be-merged/category-ads-all.yaml rm to-be-merged/cn.yaml to-be-merged/geolocation-!cn.yaml to-be-merged/category-ads-all.yaml
- name: Upload built rulesets - name: Upload built rulesets
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v7
with: with:
name: universal name: universal
path: to-be-merged path: to-be-merged
@@ -220,26 +267,26 @@ jobs:
shell: bash shell: bash
- name: Checkout repositories - name: Checkout repositories
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
repository: Loyalsoldier/v2ray-rules-dat repository: Loyalsoldier/v2ray-rules-dat
ref: hidden ref: hidden
path: . path: .
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: Loyalsoldier/domain-list-custom repository: Loyalsoldier/domain-list-custom
path: custom path: custom
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: v2fly/domain-list-community repository: v2fly/domain-list-community
path: community path: community
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: cokebar/gfwlist2dnsmasq repository: cokebar/gfwlist2dnsmasq
path: gfwlist2dnsmasq path: gfwlist2dnsmasq
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v6 uses: actions/setup-go@v7
with: with:
go-version-file: ./custom/go.mod go-version-file: ./custom/go.mod
cache-dependency-path: ./custom/go.sum cache-dependency-path: ./custom/go.sum
@@ -387,7 +434,7 @@ jobs:
curl -sSL ${APPLICATIONS} > to-be-merged/applications.yaml curl -sSL ${APPLICATIONS} > to-be-merged/applications.yaml
- name: Upload built rulesets - name: Upload built rulesets
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v7
with: with:
name: basic name: basic
path: to-be-merged path: to-be-merged
@@ -406,8 +453,8 @@ jobs:
shell: bash shell: bash
- name: Checkout repositories - name: Checkout repositories
uses: actions/checkout@v5 uses: actions/checkout@v7
- uses: actions/checkout@v5 - uses: actions/checkout@v7
with: with:
repository: xixu-me/Dandified-DLC repository: xixu-me/Dandified-DLC
path: dnf path: dnf
@@ -417,11 +464,11 @@ jobs:
mkdir -p merged converter publish redundant ntr list-final publish/yaml mkdir -p merged converter publish redundant ntr list-final publish/yaml
- name: Download rulesets - name: Download rulesets
uses: actions/download-artifact@v6 uses: actions/download-artifact@v8
with: with:
name: universal name: universal
path: universal path: universal
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v8
with: with:
name: basic name: basic
path: basic path: basic
@@ -539,7 +586,7 @@ jobs:
rm tld-!cn.mrs rm tld-!cn.mrs
- name: Release assets - name: Release assets
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v3
with: with:
name: "${{ env.RELEASE_TITLE }}" name: "${{ env.RELEASE_TITLE }}"
tag_name: "${{ env.TAG }}" tag_name: "${{ env.TAG }}"
@@ -557,7 +604,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
ref: basic ref: basic
path: basic path: basic
@@ -565,17 +612,43 @@ jobs:
- name: Purge CDN cache - name: Purge CDN cache
run: | run: |
cd basic cd basic
for file in $(ls); do failed_files=()
curl -i "https://purge.jsdelivr.net/gh/${{ github.repository }}@basic/${file}" for file in *; do
[[ -f "$file" ]] || continue
purge_url="https://purge.jsdelivr.net/gh/${{ github.repository }}@basic/${file}"
purge_succeeded=false
for attempt in 1 2 3; do
echo "Purging ${file} from basic CDN cache (attempt ${attempt}/3)"
if curl --fail --show-error --silent --location --max-time 30 "$purge_url"; then
purge_succeeded=true
echo
break
fi
if [[ $attempt -lt 3 ]]; then
echo "Retrying ${file} after transient purge failure"
sleep 2
fi
done done
if [[ $purge_succeeded == false ]]; then
failed_files+=("$file")
echo "::warning::Failed to purge jsDelivr cache for ${file} on the basic branch after 3 attempts."
fi
done
if (( ${#failed_files[@]} > 0 )); then
printf 'Files with purge warnings on basic: %s\n' "${failed_files[*]}"
fi
purge-universal-rulesets-cdn-cache: purge-universal-rulesets-cdn-cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build-and-publish-universal-rulesets needs: build-and-publish-universal-rulesets
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v7
with: with:
ref: universal ref: universal
path: universal path: universal
@@ -583,6 +656,32 @@ jobs:
- name: Purge CDN cache - name: Purge CDN cache
run: | run: |
cd universal cd universal
for file in $(ls); do failed_files=()
curl -i "https://purge.jsdelivr.net/gh/${{ github.repository }}@universal/${file}" for file in *; do
[[ -f "$file" ]] || continue
purge_url="https://purge.jsdelivr.net/gh/${{ github.repository }}@universal/${file}"
purge_succeeded=false
for attempt in 1 2 3; do
echo "Purging ${file} from universal CDN cache (attempt ${attempt}/3)"
if curl --fail --show-error --silent --location --max-time 30 "$purge_url"; then
purge_succeeded=true
echo
break
fi
if [[ $attempt -lt 3 ]]; then
echo "Retrying ${file} after transient purge failure"
sleep 2
fi
done done
if [[ $purge_succeeded == false ]]; then
failed_files+=("$file")
echo "::warning::Failed to purge jsDelivr cache for ${file} on the universal branch after 3 attempts."
fi
done
if (( ${#failed_files[@]} > 0 )); then
printf 'Files with purge warnings on universal: %s\n' "${failed_files[*]}"
fi
+202
View File
@@ -0,0 +1,202 @@
name: Dependabot Auto Merge
on:
check_suite:
types: [completed]
workflow_run:
workflows:
- "Build and Publish"
- "CodeQL"
- "Dependabot Updates"
types:
- completed
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
cancel-in-progress: false
permissions:
contents: write
pull-requests: write
checks: read
statuses: read
jobs:
merge:
name: Auto-merge Dependabot PRs
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Merge Dependabot PRs when checks pass
uses: actions/github-script@v9
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const successfulCheckConclusions = new Set(["success", "skipped", "neutral"]);
const successfulStatusStates = new Set(["success"]);
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
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);
}
}
}