mirror of
https://github.com/actions/cache.git
synced 2026-06-29 18:13:48 +08:00
Compare commits
17 Commits
2e9cddfa69
...
releases/v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
caa2961268 | ||
|
|
00c2da95da | ||
|
|
27d5ce7f10 | ||
|
|
f280785d7b | ||
|
|
619aeb1606 | ||
|
|
bcf16c2893 | ||
|
|
668228422a | ||
|
|
e34039626f | ||
|
|
8a67110529 | ||
|
|
1865903e1b | ||
|
|
5656298164 | ||
|
|
4e380d19e1 | ||
|
|
b7e8d49f17 | ||
|
|
984a21b1cb | ||
|
|
acf2f1f76a | ||
|
|
95a07c5132 | ||
|
|
90e4fae240 |
420
.github/workflows/workflow.yml
vendored
420
.github/workflows/workflow.yml
vendored
@@ -90,359 +90,187 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ubuntu:latest
|
||||
options: --privileged
|
||||
options: --cap-add=NET_ADMIN
|
||||
services:
|
||||
squid-proxy:
|
||||
image: wernight/squid
|
||||
image: ubuntu/squid:latest
|
||||
ports:
|
||||
- 3128:3128
|
||||
env:
|
||||
http_proxy: http://squid-proxy:3128
|
||||
https_proxy: http://squid-proxy:3128
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Wait for proxy to be ready
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Waiting for squid proxy to be ready..."
|
||||
echo "Resolving squid-proxy hostname:"
|
||||
getent hosts squid-proxy || echo "DNS resolution failed"
|
||||
for i in $(seq 1 30); do
|
||||
if (echo > /dev/tcp/squid-proxy/3128) 2>/dev/null; then
|
||||
echo "Proxy is ready!"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i: Proxy not ready, waiting..."
|
||||
sleep 2
|
||||
done
|
||||
echo "Proxy failed to become ready"
|
||||
exit 1
|
||||
env:
|
||||
http_proxy: ""
|
||||
https_proxy: ""
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y iptables dnsutils curl jq ipset
|
||||
- name: Fetch GitHub meta and configure firewall
|
||||
apt-get install -y iptables curl
|
||||
- name: Verify proxy is working
|
||||
run: |
|
||||
# Fetch GitHub meta API to get all IP ranges
|
||||
echo "Fetching GitHub meta API..."
|
||||
curl -sS https://api.github.com/meta > /tmp/github-meta.json
|
||||
|
||||
# Wait for squid-proxy service to be resolvable and accepting connections
|
||||
echo "Waiting for squid-proxy service..."
|
||||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
|
||||
PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }')
|
||||
if [ -n "$PROXY_IP" ]; then
|
||||
echo "squid-proxy resolved to: $PROXY_IP"
|
||||
# Test that proxy is actually accepting connections
|
||||
if curl --connect-timeout 2 --max-time 5 -x http://squid-proxy:3128 -sS https://api.github.com/zen 2>/dev/null; then
|
||||
echo "Proxy is working!"
|
||||
break
|
||||
else
|
||||
echo "Attempt $i: Proxy resolved but not ready yet, waiting..."
|
||||
fi
|
||||
else
|
||||
echo "Attempt $i: squid-proxy not resolvable yet, waiting..."
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ -z "$PROXY_IP" ]; then
|
||||
echo "ERROR: Could not resolve squid-proxy after 15 attempts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify proxy works before locking down firewall
|
||||
echo "Final proxy connectivity test..."
|
||||
if ! curl --connect-timeout 5 --max-time 10 -x http://squid-proxy:3128 -sS https://api.github.com/zen; then
|
||||
echo "ERROR: Proxy is not working properly"
|
||||
exit 1
|
||||
fi
|
||||
echo "Proxy verified working!"
|
||||
|
||||
echo "Testing proxy connectivity..."
|
||||
curl -s -o /dev/null -w "%{http_code}" --proxy http://squid-proxy:3128 http://github.com || true
|
||||
echo "Proxy verification complete"
|
||||
- name: Block direct traffic (enforce proxy usage)
|
||||
run: |
|
||||
# Get the squid-proxy container IP
|
||||
PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }')
|
||||
echo "Proxy IP: $PROXY_IP"
|
||||
|
||||
# Allow loopback traffic
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
|
||||
# Allow traffic to the proxy container
|
||||
iptables -A OUTPUT -d $PROXY_IP -j ACCEPT
|
||||
|
||||
# Allow established connections
|
||||
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# Allow loopback
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
|
||||
# Allow connections to the proxy
|
||||
iptables -A OUTPUT -d $PROXY_IP -p tcp --dport 3128 -j ACCEPT
|
||||
|
||||
# Allow DNS
|
||||
|
||||
# Allow DNS (needed for initial resolution)
|
||||
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
|
||||
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
|
||||
|
||||
# Create ipset for GitHub IPs (more efficient than individual rules)
|
||||
ipset create github-ips hash:net
|
||||
|
||||
# Add all GitHub IP ranges from meta API (hooks, web, api, git, actions, etc.)
|
||||
# EXCLUDING blob storage which must go through proxy
|
||||
for category in hooks web api git pages importer actions actions_macos codespaces copilot; do
|
||||
echo "Adding IPs for category: $category"
|
||||
jq -r ".${category}[]? // empty" /tmp/github-meta.json 2>/dev/null | while read cidr; do
|
||||
# Skip IPv6 for now (iptables vs ip6tables) - use case for POSIX compatibility
|
||||
case "$cidr" in
|
||||
*:*) ;; # IPv6, skip
|
||||
*) ipset add github-ips "$cidr" 2>/dev/null || true ;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
# Allow all GitHub IPs
|
||||
iptables -A OUTPUT -m set --match-set github-ips dst -p tcp --dport 443 -j ACCEPT
|
||||
iptables -A OUTPUT -m set --match-set github-ips dst -p tcp --dport 80 -j ACCEPT
|
||||
|
||||
# CRITICAL: Block direct access to blob storage and results-receiver
|
||||
# These MUST go through the proxy for cache operations
|
||||
echo "Blocking direct access to cache-critical endpoints..."
|
||||
|
||||
# Block results-receiver.actions.githubusercontent.com
|
||||
for ip in $(getent ahosts "results-receiver.actions.githubusercontent.com" 2>/dev/null | awk '{print $1}' | sort -u); do
|
||||
echo "Blocking direct access to results-receiver: $ip"
|
||||
iptables -I OUTPUT 1 -d "$ip" -p tcp --dport 443 -j REJECT
|
||||
done
|
||||
|
||||
# Block blob.core.windows.net (Azure blob storage used for cache)
|
||||
for host in productionresultssa0.blob.core.windows.net productionresultssa1.blob.core.windows.net productionresultssa2.blob.core.windows.net productionresultssa3.blob.core.windows.net; do
|
||||
for ip in $(getent ahosts "$host" 2>/dev/null | awk '{print $1}' | sort -u); do
|
||||
echo "Blocking direct access to blob storage ($host): $ip"
|
||||
iptables -I OUTPUT 1 -d "$ip" -p tcp --dport 443 -j REJECT
|
||||
done
|
||||
done
|
||||
|
||||
# Block all other outbound HTTP/HTTPS traffic
|
||||
|
||||
# Block all other outbound traffic (HTTP/HTTPS)
|
||||
iptables -A OUTPUT -p tcp --dport 80 -j REJECT
|
||||
iptables -A OUTPUT -p tcp --dport 443 -j REJECT
|
||||
|
||||
echo "iptables rules applied:"
|
||||
iptables -L OUTPUT -n -v
|
||||
echo ""
|
||||
echo "ipset github-ips contains $(ipset list github-ips | grep -c '^[0-9]') entries"
|
||||
- name: Verify proxy enforcement
|
||||
|
||||
# Log the iptables rules for debugging
|
||||
iptables -L -v -n
|
||||
- name: Verify direct HTTPS is blocked
|
||||
run: |
|
||||
echo "=== Testing proxy enforcement ==="
|
||||
|
||||
# Test 1: Verify proxy is working by explicitly using it
|
||||
echo "Test 1: Connection through proxy (should SUCCEED)"
|
||||
if curl --connect-timeout 10 --max-time 15 -x http://squid-proxy:3128 -sS -o /dev/null -w "%{http_code}" https://api.github.com/zen; then
|
||||
echo ""
|
||||
echo "✓ Proxy connection works"
|
||||
else
|
||||
echo "✗ ERROR: Proxy is not working!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 2: Direct connection to blob storage should FAIL (blocked by iptables)
|
||||
echo ""
|
||||
echo "Test 2: Direct connection to blob storage (should FAIL - blocked by iptables)"
|
||||
if curl --connect-timeout 5 --max-time 10 --noproxy '*' -sS https://productionresultssa0.blob.core.windows.net 2>/dev/null; then
|
||||
echo "✗ ERROR: Direct blob storage connection succeeded but should have been blocked!"
|
||||
echo "Testing that direct HTTPS requests fail..."
|
||||
if curl --noproxy '*' -s --connect-timeout 5 https://github.com > /dev/null 2>&1; then
|
||||
echo "ERROR: Direct HTTPS request succeeded - blocking is not working!"
|
||||
exit 1
|
||||
else
|
||||
echo "✓ Direct blob storage correctly blocked by iptables"
|
||||
fi
|
||||
|
||||
# Test 3: Connection to blob storage THROUGH proxy should work
|
||||
echo ""
|
||||
echo "Test 3: Connection through proxy to blob storage (should SUCCEED)"
|
||||
HTTP_CODE=$(curl --connect-timeout 10 --max-time 15 -x http://squid-proxy:3128 -sS -o /dev/null -w "%{http_code}" https://productionresultssa0.blob.core.windows.net 2>&1) || true
|
||||
echo "HTTP response code: $HTTP_CODE"
|
||||
if [ "$HTTP_CODE" = "400" ] || [ "$HTTP_CODE" = "409" ] || [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✓ Proxy successfully forwarded request to blob storage (got HTTP $HTTP_CODE)"
|
||||
else
|
||||
echo "✗ ERROR: Proxy failed to forward request (got: $HTTP_CODE)"
|
||||
exit 1
|
||||
echo "SUCCESS: Direct HTTPS request was blocked as expected"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== All proxy enforcement tests passed ==="
|
||||
echo "The proxy is working. If cache operations fail, it's because the action doesn't use the proxy."
|
||||
echo "Testing that HTTPS through proxy succeeds..."
|
||||
if curl --proxy http://squid-proxy:3128 -s --connect-timeout 10 https://github.com > /dev/null 2>&1; then
|
||||
echo "SUCCESS: HTTPS request through proxy succeeded"
|
||||
else
|
||||
echo "ERROR: HTTPS request through proxy failed!"
|
||||
exit 1
|
||||
fi
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Generate files
|
||||
run: __tests__/create-cache-files.sh proxy test-cache
|
||||
- name: Save cache
|
||||
env:
|
||||
http_proxy: http://squid-proxy:3128
|
||||
https_proxy: http://squid-proxy:3128
|
||||
uses: ./
|
||||
with:
|
||||
key: test-proxy-${{ github.run_id }}
|
||||
path: test-cache
|
||||
- name: Verify proxy setup
|
||||
run: |
|
||||
echo "## 🔒 Proxy Integration Test - Cache Save" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### ✅ Test Configuration" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Proxy**: squid-proxy:3128" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Firewall**: iptables blocking direct access to cache endpoints" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Test**: Cache save operation completed successfully through proxy" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "If the cache save step succeeded, it means:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "1. Direct access to results-receiver.actions.githubusercontent.com was blocked" >> $GITHUB_STEP_SUMMARY
|
||||
echo "2. Direct access to *.blob.core.windows.net was blocked" >> $GITHUB_STEP_SUMMARY
|
||||
echo "3. Cache operations were routed through the squid proxy" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ **SUCCESS**: Proxy integration test passed!" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
test-proxy-restore:
|
||||
needs: test-proxy-save
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ubuntu:latest
|
||||
options: --privileged
|
||||
options: --cap-add=NET_ADMIN
|
||||
services:
|
||||
squid-proxy:
|
||||
image: wernight/squid
|
||||
image: ubuntu/squid:latest
|
||||
ports:
|
||||
- 3128:3128
|
||||
env:
|
||||
http_proxy: http://squid-proxy:3128
|
||||
https_proxy: http://squid-proxy:3128
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Wait for proxy to be ready
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Waiting for squid proxy to be ready..."
|
||||
echo "Resolving squid-proxy hostname:"
|
||||
getent hosts squid-proxy || echo "DNS resolution failed"
|
||||
for i in $(seq 1 30); do
|
||||
if (echo > /dev/tcp/squid-proxy/3128) 2>/dev/null; then
|
||||
echo "Proxy is ready!"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i: Proxy not ready, waiting..."
|
||||
sleep 2
|
||||
done
|
||||
echo "Proxy failed to become ready"
|
||||
exit 1
|
||||
env:
|
||||
http_proxy: ""
|
||||
https_proxy: ""
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y iptables dnsutils curl jq ipset
|
||||
- name: Fetch GitHub meta and configure firewall
|
||||
apt-get install -y iptables curl
|
||||
- name: Verify proxy is working
|
||||
run: |
|
||||
# Fetch GitHub meta API to get all IP ranges
|
||||
echo "Fetching GitHub meta API..."
|
||||
curl -sS https://api.github.com/meta > /tmp/github-meta.json
|
||||
|
||||
# Wait for squid-proxy service to be resolvable and accepting connections
|
||||
echo "Waiting for squid-proxy service..."
|
||||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
|
||||
PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }')
|
||||
if [ -n "$PROXY_IP" ]; then
|
||||
echo "squid-proxy resolved to: $PROXY_IP"
|
||||
# Test that proxy is actually accepting connections
|
||||
if curl --connect-timeout 2 --max-time 5 -x http://squid-proxy:3128 -sS https://api.github.com/zen 2>/dev/null; then
|
||||
echo "Proxy is working!"
|
||||
break
|
||||
else
|
||||
echo "Attempt $i: Proxy resolved but not ready yet, waiting..."
|
||||
fi
|
||||
else
|
||||
echo "Attempt $i: squid-proxy not resolvable yet, waiting..."
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ -z "$PROXY_IP" ]; then
|
||||
echo "ERROR: Could not resolve squid-proxy after 15 attempts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify proxy works before locking down firewall
|
||||
echo "Final proxy connectivity test..."
|
||||
if ! curl --connect-timeout 5 --max-time 10 -x http://squid-proxy:3128 -sS https://api.github.com/zen; then
|
||||
echo "ERROR: Proxy is not working properly"
|
||||
exit 1
|
||||
fi
|
||||
echo "Proxy verified working!"
|
||||
|
||||
echo "Testing proxy connectivity..."
|
||||
curl -s -o /dev/null -w "%{http_code}" --proxy http://squid-proxy:3128 http://github.com || true
|
||||
echo "Proxy verification complete"
|
||||
- name: Block direct traffic (enforce proxy usage)
|
||||
run: |
|
||||
# Get the squid-proxy container IP
|
||||
PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }')
|
||||
echo "Proxy IP: $PROXY_IP"
|
||||
|
||||
# Allow loopback traffic
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
|
||||
# Allow traffic to the proxy container
|
||||
iptables -A OUTPUT -d $PROXY_IP -j ACCEPT
|
||||
|
||||
# Allow established connections
|
||||
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# Allow loopback
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
|
||||
# Allow connections to the proxy
|
||||
iptables -A OUTPUT -d $PROXY_IP -p tcp --dport 3128 -j ACCEPT
|
||||
|
||||
# Allow DNS
|
||||
|
||||
# Allow DNS (needed for initial resolution)
|
||||
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
|
||||
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
|
||||
|
||||
# Create ipset for GitHub IPs (more efficient than individual rules)
|
||||
ipset create github-ips hash:net
|
||||
|
||||
# Add all GitHub IP ranges from meta API (hooks, web, api, git, actions, etc.)
|
||||
# EXCLUDING blob storage which must go through proxy
|
||||
for category in hooks web api git pages importer actions actions_macos codespaces copilot; do
|
||||
echo "Adding IPs for category: $category"
|
||||
jq -r ".${category}[]? // empty" /tmp/github-meta.json 2>/dev/null | while read cidr; do
|
||||
# Skip IPv6 for now (iptables vs ip6tables) - use case for POSIX compatibility
|
||||
case "$cidr" in
|
||||
*:*) ;; # IPv6, skip
|
||||
*) ipset add github-ips "$cidr" 2>/dev/null || true ;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
# Allow all GitHub IPs
|
||||
iptables -A OUTPUT -m set --match-set github-ips dst -p tcp --dport 443 -j ACCEPT
|
||||
iptables -A OUTPUT -m set --match-set github-ips dst -p tcp --dport 80 -j ACCEPT
|
||||
|
||||
# CRITICAL: Block direct access to blob storage and results-receiver
|
||||
# These MUST go through the proxy for cache operations
|
||||
echo "Blocking direct access to cache-critical endpoints..."
|
||||
|
||||
# Block results-receiver.actions.githubusercontent.com
|
||||
for ip in $(getent ahosts "results-receiver.actions.githubusercontent.com" 2>/dev/null | awk '{print $1}' | sort -u); do
|
||||
echo "Blocking direct access to results-receiver: $ip"
|
||||
iptables -I OUTPUT 1 -d "$ip" -p tcp --dport 443 -j REJECT
|
||||
done
|
||||
|
||||
# Block blob.core.windows.net (Azure blob storage used for cache)
|
||||
for host in productionresultssa0.blob.core.windows.net productionresultssa1.blob.core.windows.net productionresultssa2.blob.core.windows.net productionresultssa3.blob.core.windows.net; do
|
||||
for ip in $(getent ahosts "$host" 2>/dev/null | awk '{print $1}' | sort -u); do
|
||||
echo "Blocking direct access to blob storage ($host): $ip"
|
||||
iptables -I OUTPUT 1 -d "$ip" -p tcp --dport 443 -j REJECT
|
||||
done
|
||||
done
|
||||
|
||||
# Block all other outbound HTTP/HTTPS traffic
|
||||
|
||||
# Block all other outbound traffic (HTTP/HTTPS)
|
||||
iptables -A OUTPUT -p tcp --dport 80 -j REJECT
|
||||
iptables -A OUTPUT -p tcp --dport 443 -j REJECT
|
||||
|
||||
echo "iptables rules applied:"
|
||||
iptables -L OUTPUT -n -v
|
||||
echo ""
|
||||
echo "ipset github-ips contains $(ipset list github-ips | grep -c '^[0-9]') entries"
|
||||
- name: Verify proxy enforcement
|
||||
|
||||
# Log the iptables rules for debugging
|
||||
iptables -L -v -n
|
||||
- name: Verify direct HTTPS is blocked
|
||||
run: |
|
||||
echo "=== Testing proxy enforcement ==="
|
||||
|
||||
# Test 1: Verify proxy is working by explicitly using it
|
||||
echo "Test 1: Connection through proxy (should SUCCEED)"
|
||||
if curl --connect-timeout 10 --max-time 15 -x http://squid-proxy:3128 -sS -o /dev/null -w "%{http_code}" https://api.github.com/zen; then
|
||||
echo ""
|
||||
echo "✓ Proxy connection works"
|
||||
else
|
||||
echo "✗ ERROR: Proxy is not working!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 2: Direct connection to blob storage should FAIL (blocked by iptables)
|
||||
echo ""
|
||||
echo "Test 2: Direct connection to blob storage (should FAIL - blocked by iptables)"
|
||||
if curl --connect-timeout 5 --max-time 10 --noproxy '*' -sS https://productionresultssa0.blob.core.windows.net 2>/dev/null; then
|
||||
echo "✗ ERROR: Direct blob storage connection succeeded but should have been blocked!"
|
||||
echo "Testing that direct HTTPS requests fail..."
|
||||
if curl --noproxy '*' -s --connect-timeout 5 https://github.com > /dev/null 2>&1; then
|
||||
echo "ERROR: Direct HTTPS request succeeded - blocking is not working!"
|
||||
exit 1
|
||||
else
|
||||
echo "✓ Direct blob storage correctly blocked by iptables"
|
||||
fi
|
||||
|
||||
# Test 3: Connection to blob storage THROUGH proxy should work
|
||||
echo ""
|
||||
echo "Test 3: Connection through proxy to blob storage (should SUCCEED)"
|
||||
HTTP_CODE=$(curl --connect-timeout 10 --max-time 15 -x http://squid-proxy:3128 -sS -o /dev/null -w "%{http_code}" https://productionresultssa0.blob.core.windows.net 2>&1) || true
|
||||
echo "HTTP response code: $HTTP_CODE"
|
||||
if [ "$HTTP_CODE" = "400" ] || [ "$HTTP_CODE" = "409" ] || [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✓ Proxy successfully forwarded request to blob storage (got HTTP $HTTP_CODE)"
|
||||
else
|
||||
echo "✗ ERROR: Proxy failed to forward request (got: $HTTP_CODE)"
|
||||
exit 1
|
||||
echo "SUCCESS: Direct HTTPS request was blocked as expected"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== All proxy enforcement tests passed ==="
|
||||
echo "The proxy is working. If cache operations fail, it's because the action doesn't use the proxy."
|
||||
echo "Testing that HTTPS through proxy succeeds..."
|
||||
if curl --proxy http://squid-proxy:3128 -s --connect-timeout 10 https://github.com > /dev/null 2>&1; then
|
||||
echo "SUCCESS: HTTPS request through proxy succeeded"
|
||||
else
|
||||
echo "ERROR: HTTPS request through proxy failed!"
|
||||
exit 1
|
||||
fi
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Restore cache
|
||||
env:
|
||||
http_proxy: http://squid-proxy:3128
|
||||
https_proxy: http://squid-proxy:3128
|
||||
uses: ./
|
||||
with:
|
||||
key: test-proxy-${{ github.run_id }}
|
||||
path: test-cache
|
||||
- name: Verify proxy setup
|
||||
run: |
|
||||
echo "## 🔒 Proxy Integration Test - Cache Restore" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### ✅ Test Configuration" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Proxy**: squid-proxy:3128" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Firewall**: iptables blocking direct access to cache endpoints" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Test**: Cache restore operation completed successfully through proxy" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "If the cache restore step succeeded, it means:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "1. Direct access to results-receiver.actions.githubusercontent.com was blocked" >> $GITHUB_STEP_SUMMARY
|
||||
echo "2. Direct access to *.blob.core.windows.net was blocked" >> $GITHUB_STEP_SUMMARY
|
||||
echo "3. Cache operations were routed through the squid proxy" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ **SUCCESS**: Proxy integration test passed!" >> $GITHUB_STEP_SUMMARY
|
||||
- name: Verify cache
|
||||
run: __tests__/verify-cache-files.sh proxy test-cache
|
||||
|
||||
2
.licenses/npm/@actions/cache.dep.yml
generated
2
.licenses/npm/@actions/cache.dep.yml
generated
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@actions/cache"
|
||||
version: 5.0.5
|
||||
version: 5.1.0
|
||||
type: npm
|
||||
summary: Actions cache lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
||||
|
||||
2
.licenses/npm/@typespec/ts-http-runtime.dep.yml
generated
2
.licenses/npm/@typespec/ts-http-runtime.dep.yml
generated
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@typespec/ts-http-runtime"
|
||||
version: 0.3.2
|
||||
version: 0.3.5
|
||||
type: npm
|
||||
summary: Isomorphic client library for making HTTP requests in node.js and browser.
|
||||
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/ts-http-runtime/
|
||||
|
||||
32
.licenses/npm/fast-xml-builder.dep.yml
generated
Normal file
32
.licenses/npm/fast-xml-builder.dep.yml
generated
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: fast-xml-builder
|
||||
version: 1.1.4
|
||||
type: npm
|
||||
summary: Build XML from JSON without C/C++ based libraries
|
||||
homepage:
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Natural Intelligence
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
notices: []
|
||||
2
.licenses/npm/fast-xml-parser.dep.yml
generated
2
.licenses/npm/fast-xml-parser.dep.yml
generated
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: fast-xml-parser
|
||||
version: 5.3.3
|
||||
version: 5.5.6
|
||||
type: npm
|
||||
summary: Validate XML, Parse XML, Build XML without C/C++ based libraries
|
||||
homepage:
|
||||
|
||||
4
.licenses/npm/minimatch.dep.yml
generated
4
.licenses/npm/minimatch.dep.yml
generated
@@ -1,9 +1,9 @@
|
||||
---
|
||||
name: minimatch
|
||||
version: 3.1.2
|
||||
version: 3.1.5
|
||||
type: npm
|
||||
summary: a glob matcher in javascript
|
||||
homepage:
|
||||
homepage:
|
||||
license: isc
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
|
||||
32
.licenses/npm/path-expression-matcher.dep.yml
generated
Normal file
32
.licenses/npm/path-expression-matcher.dep.yml
generated
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: path-expression-matcher
|
||||
version: 1.1.3
|
||||
type: npm
|
||||
summary: Efficient path tracking and pattern matching for XML/JSON parsers
|
||||
homepage: https://github.com/NaturalIntelligence/path-expression-matcher#readme
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
notices: []
|
||||
2
.licenses/npm/undici.dep.yml
generated
2
.licenses/npm/undici.dep.yml
generated
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: undici
|
||||
version: 6.23.0
|
||||
version: 6.24.1
|
||||
type: npm
|
||||
summary: An HTTP/1.1 client, written from scratch for Node.js
|
||||
homepage: https://undici.nodejs.org
|
||||
|
||||
14
README.md
14
README.md
@@ -33,7 +33,7 @@ If you do not upgrade, all workflow runs using any of the deprecated [actions/ca
|
||||
|
||||
Upgrading to the recommended versions will not break your workflows.
|
||||
|
||||
> **Additionally, if you are managing your own GitHub runners, you must update your runner version to `2.231.0` or newer to ensure compatibility with the new cache service.**
|
||||
> **Additionally, if you are managing your own GitHub runners, you must update your runner version to `2.231.0` or newer to ensure compatibility with the new cache service.**
|
||||
> Failure to update both the action version and your runner version may result in workflow failures after the migration date.
|
||||
|
||||
Read more about the change & access the migration guide: [reference to the announcement](https://github.com/actions/cache/discussions/1510).
|
||||
@@ -109,6 +109,14 @@ The cache is scoped to the key, [version](#cache-version), and branch. The defau
|
||||
|
||||
See [Matching a cache key](https://help.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key) for more info.
|
||||
|
||||
### Read-only access
|
||||
|
||||
Some workflow runs only have read-only access to the cache. A common case is a workflow triggered by a pull request from a fork: such runs can **restore** existing caches but may not be permitted to **save** new ones.
|
||||
|
||||
When the cache token is read-only, the save step does not fail the job. Instead, `@actions/cache` reports the denial once as a warning (for example, `Failed to save: ... cache write denied: ...`) and the step completes successfully without writing a cache entry. Restores in the same run continue to work as usual.
|
||||
|
||||
> **Note** This applies to the action's normal save path as well as the standalone [Save action](./save/README.md). If you intentionally want a restore-only setup, see [Make cache read only / Reuse cache from centralized job](./caching-strategies.md#make-cache-read-only--reuse-cache-from-centralized-job).
|
||||
|
||||
### Example cache workflow
|
||||
|
||||
#### Restoring and saving cache using a single action
|
||||
@@ -351,7 +359,7 @@ Please note that Windows environment variables (like `%LocalAppData%`) will NOT
|
||||
|
||||
## Note
|
||||
|
||||
Thank you for your interest in this GitHub repo, however, right now we are not taking contributions.
|
||||
Thank you for your interest in this GitHub repo, however, right now we are not taking contributions.
|
||||
|
||||
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in.
|
||||
|
||||
@@ -369,4 +377,4 @@ You are welcome to still raise bugs in this repo.
|
||||
|
||||
## License
|
||||
|
||||
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
||||
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
||||
|
||||
15
RELEASES.md
15
RELEASES.md
@@ -2,7 +2,7 @@
|
||||
|
||||
## How to prepare a release
|
||||
|
||||
> [!NOTE]
|
||||
> [!NOTE]
|
||||
> Relevant for maintainers with write access only.
|
||||
|
||||
1. Switch to a new branch from `main`.
|
||||
@@ -21,10 +21,21 @@
|
||||
1. Publish the release.
|
||||
1. Navigate to https://github.com/actions/cache/actions/workflows/release-new-action-version.yml
|
||||
1. There should be a workflow run queued with the same version number.
|
||||
1. Approve the run to publish the new version and update the major tags for this action.
|
||||
1. Approve the run to publish the new version and update the major tags for this action.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 5.1.0
|
||||
|
||||
- Bump `@actions/cache` to v5.1.0 to pick up [actions/toolkit#2435 Handle cache write error due to read-only token](https://github.com/actions/toolkit/pull/2435)
|
||||
- Switch redundant "Cache save failed" warning to debug log in save-only
|
||||
|
||||
### 5.0.4
|
||||
|
||||
- Bump `minimatch` to v3.1.5 (fixes ReDoS via globstar patterns)
|
||||
- Bump `undici` to v6.24.1 (WebSocket decompression bomb protection, header validation fixes)
|
||||
- Bump `fast-xml-parser` to v5.5.6
|
||||
|
||||
### 5.0.3
|
||||
|
||||
- Bump `@actions/cache` to v5.0.5 (Resolves: https://github.com/actions/cache/security/dependabot/33)
|
||||
|
||||
@@ -105,8 +105,10 @@ test("save with valid inputs uploads a cache", async () => {
|
||||
expect(failedMock).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test("save failing logs the warning message", async () => {
|
||||
test("save failing logs the debug message", async () => {
|
||||
const debugMock = jest.spyOn(core, "debug");
|
||||
const warningMock = jest.spyOn(core, "warning");
|
||||
const failedMock = jest.spyOn(core, "setFailed");
|
||||
|
||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
||||
|
||||
@@ -115,6 +117,9 @@ test("save failing logs the warning message", async () => {
|
||||
testUtils.setInput(Inputs.Path, inputPath);
|
||||
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
|
||||
|
||||
// A read-only / write-denied save surfaces to the action as saveCache resolving
|
||||
// to -1; the toolkit has already logged the underlying reason. The action
|
||||
// must not fail the job or emit its own warning.
|
||||
const cacheId = -1;
|
||||
const saveCacheMock = jest
|
||||
.spyOn(cache, "saveCache")
|
||||
@@ -134,6 +139,7 @@ test("save failing logs the warning message", async () => {
|
||||
false
|
||||
);
|
||||
|
||||
expect(warningMock).toHaveBeenCalledTimes(1);
|
||||
expect(warningMock).toHaveBeenCalledWith("Cache save failed.");
|
||||
expect(debugMock).toHaveBeenCalledWith("Cache was not saved.");
|
||||
expect(warningMock).not.toHaveBeenCalled();
|
||||
expect(failedMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
8290
dist/restore-only/index.js
vendored
8290
dist/restore-only/index.js
vendored
File diff suppressed because one or more lines are too long
8290
dist/restore/index.js
vendored
8290
dist/restore/index.js
vendored
File diff suppressed because one or more lines are too long
8296
dist/save-only/index.js
vendored
8296
dist/save-only/index.js
vendored
File diff suppressed because one or more lines are too long
8296
dist/save/index.js
vendored
8296
dist/save/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -49,7 +49,7 @@
|
||||
with:
|
||||
path: |
|
||||
~/.bun/install/cache
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||
```
|
||||
|
||||
### Windows
|
||||
@@ -59,7 +59,7 @@
|
||||
with:
|
||||
path: |
|
||||
~\.bun
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||
```
|
||||
|
||||
## C# - NuGet
|
||||
|
||||
92
package-lock.json
generated
92
package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "cache",
|
||||
"version": "5.0.2",
|
||||
"version": "5.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "cache",
|
||||
"version": "5.0.2",
|
||||
"version": "5.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^5.0.5",
|
||||
"@actions/cache": "^5.1.0",
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/io": "^2.0.0"
|
||||
@@ -39,9 +39,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/cache": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.0.5.tgz",
|
||||
"integrity": "sha512-jiQSg0gfd+C2KPgcmdCOq7dCuCIQQWQ4b1YfGIRaaA9w7PJbRwTOcCz4LiFEUnqZGf0ha/8OKL3BeNwetHzYsQ==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.1.0.tgz",
|
||||
"integrity": "sha512-kTIj4YPrjjRPKSGlj7f8eq+Pijoy/SKBEbJcAwNsQTFGEF29NGqj1mqD02/PmhV6r4bRAixycexAWpmUJ2aCwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^2.0.0",
|
||||
@@ -1875,13 +1875,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
@@ -1945,9 +1945,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typespec/ts-http-runtime": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz",
|
||||
"integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==",
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.5.tgz",
|
||||
"integrity": "sha512-yURCknZhvywvQItHMMmFSo+fq5arCUIyz/CVk7jD89MSai7dkaX8ufjCWp3NttLojoTVbcE72ri+be/TnEbMHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"http-proxy-agent": "^7.0.0",
|
||||
@@ -2008,9 +2008,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
|
||||
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -3741,10 +3741,10 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-xml-parser": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.3.tgz",
|
||||
"integrity": "sha512-2O3dkPAAC6JavuMm8+4+pgTk+5hoAs+CjZ+sWcQLkX9+/tHRuTkQh/Oaifr8qDmZ8iEHb771Ea6G8CdwkrgvYA==",
|
||||
"node_modules/fast-xml-builder": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
|
||||
"integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -3753,7 +3753,24 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"strnum": "^2.1.0"
|
||||
"path-expression-matcher": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-xml-parser": {
|
||||
"version": "5.5.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.6.tgz",
|
||||
"integrity": "sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-xml-builder": "^1.1.4",
|
||||
"path-expression-matcher": "^1.1.3",
|
||||
"strnum": "^2.1.2"
|
||||
},
|
||||
"bin": {
|
||||
"fxparser": "src/cli/cli.js"
|
||||
@@ -3838,9 +3855,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
|
||||
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -5805,9 +5822,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
@@ -6141,6 +6158,21 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-expression-matcher": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.1.3.tgz",
|
||||
"integrity": "sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
@@ -7462,9 +7494,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
|
||||
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cache",
|
||||
"version": "5.0.3",
|
||||
"version": "5.1.0",
|
||||
"private": true,
|
||||
"description": "Cache dependencies and build outputs",
|
||||
"main": "dist/restore/index.js",
|
||||
@@ -23,7 +23,7 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^5.0.5",
|
||||
"@actions/cache": "^5.1.0",
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/io": "^2.0.0"
|
||||
@@ -51,4 +51,4 @@
|
||||
"engines": {
|
||||
"node": ">=24"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,11 @@ export async function saveOnlyRun(
|
||||
try {
|
||||
const cacheId = await saveImpl(new NullStateProvider());
|
||||
if (cacheId === -1) {
|
||||
core.warning(`Cache save failed.`);
|
||||
// The toolkit's saveCache already logs the underlying reason at
|
||||
// the appropriate severity (warning for most failures, info for
|
||||
// benign concurrency races, error for 5xx). Avoid emitting a
|
||||
// generic warning here that would duplicate or mask that signal.
|
||||
core.debug(`Cache was not saved.`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
Reference in New Issue
Block a user