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
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ubuntu:latest
|
image: ubuntu:latest
|
||||||
options: --privileged
|
options: --cap-add=NET_ADMIN
|
||||||
services:
|
services:
|
||||||
squid-proxy:
|
squid-proxy:
|
||||||
image: wernight/squid
|
image: ubuntu/squid:latest
|
||||||
ports:
|
ports:
|
||||||
- 3128:3128
|
- 3128:3128
|
||||||
|
env:
|
||||||
|
http_proxy: http://squid-proxy:3128
|
||||||
|
https_proxy: http://squid-proxy:3128
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Wait for proxy to be ready
|
||||||
uses: actions/checkout@v5
|
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
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y iptables dnsutils curl jq ipset
|
apt-get install -y iptables curl
|
||||||
- name: Fetch GitHub meta and configure firewall
|
- name: Verify proxy is working
|
||||||
run: |
|
run: |
|
||||||
# Fetch GitHub meta API to get all IP ranges
|
echo "Testing proxy connectivity..."
|
||||||
echo "Fetching GitHub meta API..."
|
curl -s -o /dev/null -w "%{http_code}" --proxy http://squid-proxy:3128 http://github.com || true
|
||||||
curl -sS https://api.github.com/meta > /tmp/github-meta.json
|
echo "Proxy verification complete"
|
||||||
|
- name: Block direct traffic (enforce proxy usage)
|
||||||
# Wait for squid-proxy service to be resolvable and accepting connections
|
run: |
|
||||||
echo "Waiting for squid-proxy service..."
|
# Get the squid-proxy container IP
|
||||||
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 }')
|
||||||
PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }')
|
echo "Proxy IP: $PROXY_IP"
|
||||||
if [ -n "$PROXY_IP" ]; then
|
|
||||||
echo "squid-proxy resolved to: $PROXY_IP"
|
# Allow loopback traffic
|
||||||
# Test that proxy is actually accepting connections
|
iptables -A OUTPUT -o lo -j ACCEPT
|
||||||
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!"
|
# Allow traffic to the proxy container
|
||||||
break
|
iptables -A OUTPUT -d $PROXY_IP -j ACCEPT
|
||||||
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!"
|
|
||||||
|
|
||||||
# Allow established connections
|
# Allow established connections
|
||||||
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
# Allow loopback
|
# Allow DNS (needed for initial resolution)
|
||||||
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
|
|
||||||
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
|
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
|
||||||
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
|
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
|
||||||
|
|
||||||
# Create ipset for GitHub IPs (more efficient than individual rules)
|
# Block all other outbound traffic (HTTP/HTTPS)
|
||||||
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
|
|
||||||
iptables -A OUTPUT -p tcp --dport 80 -j REJECT
|
iptables -A OUTPUT -p tcp --dport 80 -j REJECT
|
||||||
iptables -A OUTPUT -p tcp --dport 443 -j REJECT
|
iptables -A OUTPUT -p tcp --dport 443 -j REJECT
|
||||||
|
|
||||||
echo "iptables rules applied:"
|
# Log the iptables rules for debugging
|
||||||
iptables -L OUTPUT -n -v
|
iptables -L -v -n
|
||||||
echo ""
|
- name: Verify direct HTTPS is blocked
|
||||||
echo "ipset github-ips contains $(ipset list github-ips | grep -c '^[0-9]') entries"
|
|
||||||
- name: Verify proxy enforcement
|
|
||||||
run: |
|
run: |
|
||||||
echo "=== Testing proxy enforcement ==="
|
echo "Testing that direct HTTPS requests fail..."
|
||||||
|
if curl --noproxy '*' -s --connect-timeout 5 https://github.com > /dev/null 2>&1; then
|
||||||
# Test 1: Verify proxy is working by explicitly using it
|
echo "ERROR: Direct HTTPS request succeeded - blocking is not working!"
|
||||||
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!"
|
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo "✓ Direct blob storage correctly blocked by iptables"
|
echo "SUCCESS: Direct HTTPS request was blocked as expected"
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo "Testing that HTTPS through proxy succeeds..."
|
||||||
echo "=== All proxy enforcement tests passed ==="
|
if curl --proxy http://squid-proxy:3128 -s --connect-timeout 10 https://github.com > /dev/null 2>&1; then
|
||||||
echo "The proxy is working. If cache operations fail, it's because the action doesn't use the proxy."
|
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
|
- name: Generate files
|
||||||
run: __tests__/create-cache-files.sh proxy test-cache
|
run: __tests__/create-cache-files.sh proxy test-cache
|
||||||
- name: Save cache
|
- name: Save cache
|
||||||
env:
|
|
||||||
http_proxy: http://squid-proxy:3128
|
|
||||||
https_proxy: http://squid-proxy:3128
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
key: test-proxy-${{ github.run_id }}
|
key: test-proxy-${{ github.run_id }}
|
||||||
path: test-cache
|
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:
|
test-proxy-restore:
|
||||||
needs: test-proxy-save
|
needs: test-proxy-save
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ubuntu:latest
|
image: ubuntu:latest
|
||||||
options: --privileged
|
options: --cap-add=NET_ADMIN
|
||||||
services:
|
services:
|
||||||
squid-proxy:
|
squid-proxy:
|
||||||
image: wernight/squid
|
image: ubuntu/squid:latest
|
||||||
ports:
|
ports:
|
||||||
- 3128:3128
|
- 3128:3128
|
||||||
|
env:
|
||||||
|
http_proxy: http://squid-proxy:3128
|
||||||
|
https_proxy: http://squid-proxy:3128
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Wait for proxy to be ready
|
||||||
uses: actions/checkout@v5
|
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
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y iptables dnsutils curl jq ipset
|
apt-get install -y iptables curl
|
||||||
- name: Fetch GitHub meta and configure firewall
|
- name: Verify proxy is working
|
||||||
run: |
|
run: |
|
||||||
# Fetch GitHub meta API to get all IP ranges
|
echo "Testing proxy connectivity..."
|
||||||
echo "Fetching GitHub meta API..."
|
curl -s -o /dev/null -w "%{http_code}" --proxy http://squid-proxy:3128 http://github.com || true
|
||||||
curl -sS https://api.github.com/meta > /tmp/github-meta.json
|
echo "Proxy verification complete"
|
||||||
|
- name: Block direct traffic (enforce proxy usage)
|
||||||
# Wait for squid-proxy service to be resolvable and accepting connections
|
run: |
|
||||||
echo "Waiting for squid-proxy service..."
|
# Get the squid-proxy container IP
|
||||||
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 }')
|
||||||
PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }')
|
echo "Proxy IP: $PROXY_IP"
|
||||||
if [ -n "$PROXY_IP" ]; then
|
|
||||||
echo "squid-proxy resolved to: $PROXY_IP"
|
# Allow loopback traffic
|
||||||
# Test that proxy is actually accepting connections
|
iptables -A OUTPUT -o lo -j ACCEPT
|
||||||
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!"
|
# Allow traffic to the proxy container
|
||||||
break
|
iptables -A OUTPUT -d $PROXY_IP -j ACCEPT
|
||||||
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!"
|
|
||||||
|
|
||||||
# Allow established connections
|
# Allow established connections
|
||||||
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
# Allow loopback
|
# Allow DNS (needed for initial resolution)
|
||||||
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
|
|
||||||
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
|
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
|
||||||
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
|
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
|
||||||
|
|
||||||
# Create ipset for GitHub IPs (more efficient than individual rules)
|
# Block all other outbound traffic (HTTP/HTTPS)
|
||||||
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
|
|
||||||
iptables -A OUTPUT -p tcp --dport 80 -j REJECT
|
iptables -A OUTPUT -p tcp --dport 80 -j REJECT
|
||||||
iptables -A OUTPUT -p tcp --dport 443 -j REJECT
|
iptables -A OUTPUT -p tcp --dport 443 -j REJECT
|
||||||
|
|
||||||
echo "iptables rules applied:"
|
# Log the iptables rules for debugging
|
||||||
iptables -L OUTPUT -n -v
|
iptables -L -v -n
|
||||||
echo ""
|
- name: Verify direct HTTPS is blocked
|
||||||
echo "ipset github-ips contains $(ipset list github-ips | grep -c '^[0-9]') entries"
|
|
||||||
- name: Verify proxy enforcement
|
|
||||||
run: |
|
run: |
|
||||||
echo "=== Testing proxy enforcement ==="
|
echo "Testing that direct HTTPS requests fail..."
|
||||||
|
if curl --noproxy '*' -s --connect-timeout 5 https://github.com > /dev/null 2>&1; then
|
||||||
# Test 1: Verify proxy is working by explicitly using it
|
echo "ERROR: Direct HTTPS request succeeded - blocking is not working!"
|
||||||
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!"
|
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo "✓ Direct blob storage correctly blocked by iptables"
|
echo "SUCCESS: Direct HTTPS request was blocked as expected"
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo "Testing that HTTPS through proxy succeeds..."
|
||||||
echo "=== All proxy enforcement tests passed ==="
|
if curl --proxy http://squid-proxy:3128 -s --connect-timeout 10 https://github.com > /dev/null 2>&1; then
|
||||||
echo "The proxy is working. If cache operations fail, it's because the action doesn't use the proxy."
|
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
|
- name: Restore cache
|
||||||
env:
|
|
||||||
http_proxy: http://squid-proxy:3128
|
|
||||||
https_proxy: http://squid-proxy:3128
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
key: test-proxy-${{ github.run_id }}
|
key: test-proxy-${{ github.run_id }}
|
||||||
path: test-cache
|
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
|
- name: Verify cache
|
||||||
run: __tests__/verify-cache-files.sh proxy test-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"
|
name: "@actions/cache"
|
||||||
version: 5.0.5
|
version: 5.1.0
|
||||||
type: npm
|
type: npm
|
||||||
summary: Actions cache lib
|
summary: Actions cache lib
|
||||||
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
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"
|
name: "@typespec/ts-http-runtime"
|
||||||
version: 0.3.2
|
version: 0.3.5
|
||||||
type: npm
|
type: npm
|
||||||
summary: Isomorphic client library for making HTTP requests in node.js and browser.
|
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/
|
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
|
name: fast-xml-parser
|
||||||
version: 5.3.3
|
version: 5.5.6
|
||||||
type: npm
|
type: npm
|
||||||
summary: Validate XML, Parse XML, Build XML without C/C++ based libraries
|
summary: Validate XML, Parse XML, Build XML without C/C++ based libraries
|
||||||
homepage:
|
homepage:
|
||||||
|
|||||||
4
.licenses/npm/minimatch.dep.yml
generated
4
.licenses/npm/minimatch.dep.yml
generated
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: minimatch
|
name: minimatch
|
||||||
version: 3.1.2
|
version: 3.1.5
|
||||||
type: npm
|
type: npm
|
||||||
summary: a glob matcher in javascript
|
summary: a glob matcher in javascript
|
||||||
homepage:
|
homepage:
|
||||||
license: isc
|
license: isc
|
||||||
licenses:
|
licenses:
|
||||||
- sources: LICENSE
|
- 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
|
name: undici
|
||||||
version: 6.23.0
|
version: 6.24.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: An HTTP/1.1 client, written from scratch for Node.js
|
summary: An HTTP/1.1 client, written from scratch for Node.js
|
||||||
homepage: https://undici.nodejs.org
|
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.
|
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.
|
> 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).
|
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.
|
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
|
### Example cache workflow
|
||||||
|
|
||||||
#### Restoring and saving cache using a single action
|
#### Restoring and saving cache using a single action
|
||||||
@@ -351,7 +359,7 @@ Please note that Windows environment variables (like `%LocalAppData%`) will NOT
|
|||||||
|
|
||||||
## Note
|
## 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.
|
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
|
## 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
|
## How to prepare a release
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Relevant for maintainers with write access only.
|
> Relevant for maintainers with write access only.
|
||||||
|
|
||||||
1. Switch to a new branch from `main`.
|
1. Switch to a new branch from `main`.
|
||||||
@@ -21,10 +21,21 @@
|
|||||||
1. Publish the release.
|
1. Publish the release.
|
||||||
1. Navigate to https://github.com/actions/cache/actions/workflows/release-new-action-version.yml
|
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. 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
|
## 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
|
### 5.0.3
|
||||||
|
|
||||||
- Bump `@actions/cache` to v5.0.5 (Resolves: https://github.com/actions/cache/security/dependabot/33)
|
- 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);
|
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 warningMock = jest.spyOn(core, "warning");
|
||||||
|
const failedMock = jest.spyOn(core, "setFailed");
|
||||||
|
|
||||||
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
|
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.Path, inputPath);
|
||||||
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
|
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 cacheId = -1;
|
||||||
const saveCacheMock = jest
|
const saveCacheMock = jest
|
||||||
.spyOn(cache, "saveCache")
|
.spyOn(cache, "saveCache")
|
||||||
@@ -134,6 +139,7 @@ test("save failing logs the warning message", async () => {
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(warningMock).toHaveBeenCalledTimes(1);
|
expect(debugMock).toHaveBeenCalledWith("Cache was not saved.");
|
||||||
expect(warningMock).toHaveBeenCalledWith("Cache save failed.");
|
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:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.bun/install/cache
|
~/.bun/install/cache
|
||||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~\.bun
|
~\.bun
|
||||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||||
```
|
```
|
||||||
|
|
||||||
## C# - NuGet
|
## C# - NuGet
|
||||||
|
|||||||
92
package-lock.json
generated
92
package-lock.json
generated
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"version": "5.0.2",
|
"version": "5.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"version": "5.0.2",
|
"version": "5.1.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^5.0.5",
|
"@actions/cache": "^5.1.0",
|
||||||
"@actions/core": "^2.0.3",
|
"@actions/core": "^2.0.3",
|
||||||
"@actions/exec": "^2.0.0",
|
"@actions/exec": "^2.0.0",
|
||||||
"@actions/io": "^2.0.0"
|
"@actions/io": "^2.0.0"
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/cache": {
|
"node_modules/@actions/cache": {
|
||||||
"version": "5.0.5",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.1.0.tgz",
|
||||||
"integrity": "sha512-jiQSg0gfd+C2KPgcmdCOq7dCuCIQQWQ4b1YfGIRaaA9w7PJbRwTOcCz4LiFEUnqZGf0ha/8OKL3BeNwetHzYsQ==",
|
"integrity": "sha512-kTIj4YPrjjRPKSGlj7f8eq+Pijoy/SKBEbJcAwNsQTFGEF29NGqj1mqD02/PmhV6r4bRAixycexAWpmUJ2aCwg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^2.0.0",
|
"@actions/core": "^2.0.0",
|
||||||
@@ -1875,13 +1875,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||||
"version": "9.0.5",
|
"version": "9.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^2.0.1"
|
"brace-expansion": "^2.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16 || 14 >=14.17"
|
"node": ">=16 || 14 >=14.17"
|
||||||
@@ -1945,9 +1945,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typespec/ts-http-runtime": {
|
"node_modules/@typespec/ts-http-runtime": {
|
||||||
"version": "0.3.2",
|
"version": "0.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.5.tgz",
|
||||||
"integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==",
|
"integrity": "sha512-yURCknZhvywvQItHMMmFSo+fq5arCUIyz/CVk7jD89MSai7dkaX8ufjCWp3NttLojoTVbcE72ri+be/TnEbMHw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"http-proxy-agent": "^7.0.0",
|
"http-proxy-agent": "^7.0.0",
|
||||||
@@ -2008,9 +2008,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ajv": {
|
"node_modules/ajv": {
|
||||||
"version": "6.12.6",
|
"version": "6.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
|
||||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -3741,10 +3741,10 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fast-xml-parser": {
|
"node_modules/fast-xml-builder": {
|
||||||
"version": "5.3.3",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
|
||||||
"integrity": "sha512-2O3dkPAAC6JavuMm8+4+pgTk+5hoAs+CjZ+sWcQLkX9+/tHRuTkQh/Oaifr8qDmZ8iEHb771Ea6G8CdwkrgvYA==",
|
"integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -3753,7 +3753,24 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"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": {
|
"bin": {
|
||||||
"fxparser": "src/cli/cli.js"
|
"fxparser": "src/cli/cli.js"
|
||||||
@@ -3838,9 +3855,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
"version": "3.3.3",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||||
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
|
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -5805,9 +5822,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
@@ -6141,6 +6158,21 @@
|
|||||||
"node": ">=8"
|
"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": {
|
"node_modules/path-is-absolute": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
@@ -7462,9 +7494,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.23.0",
|
"version": "6.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||||
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
|
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17"
|
"node": ">=18.17"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"version": "5.0.3",
|
"version": "5.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Cache dependencies and build outputs",
|
"description": "Cache dependencies and build outputs",
|
||||||
"main": "dist/restore/index.js",
|
"main": "dist/restore/index.js",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^5.0.5",
|
"@actions/cache": "^5.1.0",
|
||||||
"@actions/core": "^2.0.3",
|
"@actions/core": "^2.0.3",
|
||||||
"@actions/exec": "^2.0.0",
|
"@actions/exec": "^2.0.0",
|
||||||
"@actions/io": "^2.0.0"
|
"@actions/io": "^2.0.0"
|
||||||
@@ -51,4 +51,4 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=24"
|
"node": ">=24"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,11 @@ export async function saveOnlyRun(
|
|||||||
try {
|
try {
|
||||||
const cacheId = await saveImpl(new NullStateProvider());
|
const cacheId = await saveImpl(new NullStateProvider());
|
||||||
if (cacheId === -1) {
|
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) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|||||||
Reference in New Issue
Block a user