Skip to content

Commit 78258d2

Browse files
authored
Fix publish dryrun when -sys crates update (#840)
1 parent 3efb4fa commit 78258d2

File tree

2 files changed

+309
-3
lines changed

2 files changed

+309
-3
lines changed

.github/workflows/integration.yml

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,57 @@ jobs:
150150
working-directory: ./links-testing
151151
run: cargo run --features ${{ matrix.features }} --no-default-features
152152

153-
publish-dry-run:
153+
publish-dry-run-version-check:
154154
if: github.repository_owner == 'aws'
155-
name: publish dry-run
155+
name: publish dry-run version check
156+
runs-on: ubuntu-latest
157+
outputs:
158+
skip-aws-lc-rs: ${{ steps.check.outputs.skip-aws-lc-rs }}
159+
reason: ${{ steps.check.outputs.reason }}
160+
steps:
161+
- uses: actions/checkout@v3
162+
- name: Check sys crate version compatibility
163+
id: check
164+
run: |
165+
# Run the compatibility check script
166+
if output=$(./scripts/ci/check_sys_crate_compatibility.sh 2>&1); then
167+
should_skip=$(echo "$output" | grep "^SHOULD_SKIP=" | cut -d'=' -f2-)
168+
echo "Detected: SHOULD_SKIP=$should_skip"
169+
echo "skip-aws-lc-rs=${should_skip}" >> $GITHUB_OUTPUT
170+
echo "reason=" >> $GITHUB_OUTPUT
171+
echo Successful publish compatibility check
172+
echo "$output"
173+
exit 0
174+
else
175+
exit_code=$?
176+
echo Failed publish compatibility check with exit code $exit_code
177+
echo "$output"
178+
179+
if [ $exit_code -eq 1 ]; then
180+
# Script returned 1 (incompatible - should skip)
181+
echo "skip-aws-lc-rs=true" >> $GITHUB_OUTPUT
182+
183+
# Extract skip reason from output
184+
skip_reason=$(echo "$output" | grep "^SKIP_REASON=" | cut -d'=' -f2-)
185+
echo "reason=$skip_reason" >> $GITHUB_OUTPUT
186+
exit 1
187+
else
188+
# Script returned 2 (error)
189+
echo "::error::Script execution failed with exit code $exit_code"
190+
exit $exit_code
191+
fi
192+
fi
193+
194+
publish-dry-run-sys-crates:
195+
if: github.repository_owner == 'aws'
196+
name: publish dry-run (sys crates)
156197
runs-on: ${{ matrix.os }}
157198
strategy:
158199
fail-fast: false
159200
matrix:
160201
rust: [ stable ]
161202
os: [ windows-latest, ubuntu-latest, macos-13, macos-latest ]
162-
crate: [ aws-lc-sys, aws-lc-rs, aws-lc-fips-sys ]
203+
crate: [ aws-lc-sys, aws-lc-fips-sys ]
163204
args:
164205
- publish --dry-run
165206
steps:
@@ -193,6 +234,49 @@ jobs:
193234
working-directory: ./${{ matrix.crate }}
194235
run: cargo publish --dry-run
195236

237+
publish-dry-run-main-crate:
238+
if: github.repository_owner == 'aws' && needs.publish-dry-run-version-check.outputs.skip-aws-lc-rs != 'true'
239+
name: publish dry-run (aws-lc-rs)
240+
needs: publish-dry-run-version-check
241+
runs-on: ${{ matrix.os }}
242+
strategy:
243+
fail-fast: false
244+
matrix:
245+
rust: [ stable ]
246+
os: [ windows-latest, ubuntu-latest, macos-13, macos-latest ]
247+
args:
248+
- publish --dry-run
249+
steps:
250+
- uses: actions/setup-go@v4
251+
with:
252+
go-version: '>=1.18'
253+
- run: go version
254+
- uses: actions/checkout@v3
255+
with:
256+
submodules: 'recursive'
257+
- if: ${{ matrix.os == 'windows-latest' }}
258+
uses: ilammy/setup-nasm@v1
259+
- name: Install ninja-build tool
260+
if: ${{ matrix.os == 'windows-latest' }}
261+
uses: seanmiddleditch/gha-setup-ninja@v4
262+
- uses: dtolnay/rust-toolchain@master
263+
id: toolchain
264+
with:
265+
toolchain: ${{ matrix.rust }}
266+
- name: Set Rust toolchain override
267+
run: rustup override set ${{ steps.toolchain.outputs.name }}
268+
- name: aws-lc-rs
269+
working-directory: ./aws-lc-rs
270+
run: cargo ${{ matrix.args }}
271+
- name: Clean
272+
run: cargo clean
273+
- name: Force Linux shared build
274+
env:
275+
AWS_LC_SYS_STATIC: 0
276+
AWS_LC_FIPS_SYS_STATIC: 0
277+
working-directory: ./aws-lc-rs
278+
run: cargo publish --dry-run
279+
196280
## Verify that prebuilt-nasm objects were published properly
197281
publish-dry-run-prebuild-nasm:
198282
if: github.repository_owner == 'aws'
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
#!/bin/bash
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
# SPDX-License-Identifier: Apache-2.0 OR ISC
4+
set -euo pipefail
5+
6+
# Script to check if sys crate versions referenced in aws-lc-rs are compatible
7+
# with what's available on crates.io. Used to determine if aws-lc-rs publish
8+
# dry-run should be skipped due to unpublished sys crate dependencies.
9+
#
10+
# Exit codes:
11+
# 0 = Compatible (aws-lc-rs can be published)
12+
# 1 = Incompatible (aws-lc-rs should skip publish due to major/minor version changes)
13+
# 2 = Error in script execution
14+
15+
main() {
16+
local cargo_toml_path="${1:-aws-lc-rs/Cargo.toml}"
17+
18+
# Parse aws-lc-rs/Cargo.toml to extract sys crate versions
19+
local aws_lc_sys_version
20+
local aws_lc_fips_sys_version
21+
22+
aws_lc_sys_version=$(grep 'aws-lc-sys.*=' "$cargo_toml_path" | sed 's/.*version = "\([^"]*\)".*/\1/')
23+
aws_lc_fips_sys_version=$(grep 'aws-lc-fips-sys.*=' "$cargo_toml_path" | sed 's/.*version = "\([^"]*\)".*/\1/')
24+
25+
if [[ -z "$aws_lc_sys_version" || -z "$aws_lc_fips_sys_version" ]]; then
26+
echo "Error: Could not extract sys crate versions from $cargo_toml_path" >&2
27+
exit 2
28+
fi
29+
30+
echo "Local aws-lc-sys version: $aws_lc_sys_version"
31+
echo "Local aws-lc-fips-sys version: $aws_lc_fips_sys_version"
32+
33+
local skip_reason=""
34+
local should_skip=false
35+
36+
# Check aws-lc-sys
37+
echo "Checking aws-lc-sys version $aws_lc_sys_version on crates.io..."
38+
if ! check_version_exists "aws-lc-sys" "$aws_lc_sys_version"; then
39+
echo "aws-lc-sys version $aws_lc_sys_version not found on crates.io"
40+
local latest_aws_lc_sys
41+
if ! latest_aws_lc_sys=$(get_latest_version "aws-lc-sys"); then
42+
echo "Error: Failed to get latest version for aws-lc-sys" >&2
43+
exit 2
44+
fi
45+
echo "Latest aws-lc-sys version on crates.io: $latest_aws_lc_sys"
46+
47+
if ! compare_versions "$aws_lc_sys_version" "$latest_aws_lc_sys"; then
48+
should_skip=true
49+
skip_reason="aws-lc-sys version $aws_lc_sys_version not published (major/minor version change from $latest_aws_lc_sys)"
50+
echo "aws-lc-sys: Major/minor version change detected"
51+
else
52+
echo "aws-lc-sys: Only patch version difference, compatible"
53+
fi
54+
else
55+
echo "aws-lc-sys version $aws_lc_sys_version found on crates.io"
56+
fi
57+
58+
# Check aws-lc-fips-sys
59+
echo "Checking aws-lc-fips-sys version $aws_lc_fips_sys_version on crates.io..."
60+
if ! check_version_exists "aws-lc-fips-sys" "$aws_lc_fips_sys_version"; then
61+
echo "aws-lc-fips-sys version $aws_lc_fips_sys_version not found on crates.io"
62+
local latest_aws_lc_fips_sys
63+
if ! latest_aws_lc_fips_sys=$(get_latest_version "aws-lc-fips-sys"); then
64+
echo "Error: Failed to get latest version for aws-lc-fips-sys" >&2
65+
exit 2
66+
fi
67+
echo "Latest aws-lc-fips-sys version on crates.io: $latest_aws_lc_fips_sys"
68+
69+
if ! compare_versions "$aws_lc_fips_sys_version" "$latest_aws_lc_fips_sys"; then
70+
should_skip=true
71+
if [[ -n "$skip_reason" ]]; then
72+
skip_reason="$skip_reason; aws-lc-fips-sys version $aws_lc_fips_sys_version not published (major/minor version change from $latest_aws_lc_fips_sys)"
73+
else
74+
skip_reason="aws-lc-fips-sys version $aws_lc_fips_sys_version not published (major/minor version change from $latest_aws_lc_fips_sys)"
75+
fi
76+
echo "aws-lc-fips-sys: Major/minor version change detected"
77+
else
78+
echo "aws-lc-fips-sys: Only patch version difference, compatible"
79+
fi
80+
else
81+
echo "aws-lc-fips-sys version $aws_lc_fips_sys_version found on crates.io"
82+
fi
83+
84+
# Output results
85+
echo "Final decision: should_skip=$should_skip"
86+
if [[ "$should_skip" == "true" ]]; then
87+
echo "::notice::Skipping aws-lc-rs publish dry-run: $skip_reason"
88+
echo "SHOULD_SKIP=true"
89+
echo "SKIP_REASON=$skip_reason"
90+
else
91+
echo "::notice::All sys crate versions are compatible, aws-lc-rs publish dry-run will proceed"
92+
echo "SHOULD_SKIP=false"
93+
echo "SKIP_REASON="
94+
fi
95+
}
96+
97+
# Function to check if version exists on crates.io
98+
check_version_exists() {
99+
local crate_name=$1
100+
local version=$2
101+
local response
102+
local http_code
103+
104+
echo " Fetching versions for $crate_name..."
105+
106+
# Use curl with verbose error reporting
107+
if response=$(curl -s --max-time 30 --retry 2 --retry-delay 1 \
108+
--user-agent "aws-lc-rs-version-check" \
109+
--write-out "HTTPSTATUS:%{http_code}" \
110+
"https://crates.io/api/v1/crates/$crate_name/versions" 2>&1); then
111+
112+
# Extract HTTP status code
113+
http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
114+
response=$(echo "$response" | sed 's/HTTPSTATUS:[0-9]*$//')
115+
116+
echo " HTTP status: $http_code"
117+
118+
if [[ "$http_code" == "200" ]] && [[ -n "$response" ]]; then
119+
echo " Successfully fetched versions"
120+
else
121+
echo " HTTP error $http_code"
122+
return 1
123+
fi
124+
else
125+
echo " Curl failed: " $?
126+
return 1
127+
fi
128+
129+
if [[ -z "$response" ]]; then
130+
echo " Warning: Empty response for $crate_name versions"
131+
echo " Assuming version exists to avoid false negatives"
132+
return 0 # Assume version exists to avoid false negatives
133+
fi
134+
135+
echo " Searching for version $version in response..."
136+
if echo "$response" | grep -q "\"num\":\"$version\""; then
137+
echo " Found version $version"
138+
return 0
139+
else
140+
echo " Version $version not found"
141+
return 1
142+
fi
143+
}
144+
145+
# Function to get latest published version
146+
get_latest_version() {
147+
local crate_name=$1
148+
local response
149+
local max_version
150+
local http_code
151+
152+
echo " Fetching crate info for $crate_name..." >&2
153+
154+
if response=$(curl -s --max-time 30 --retry 2 --retry-delay 1 \
155+
--user-agent "aws-lc-rs-version-check" \
156+
--write-out "HTTPSTATUS:%{http_code}" \
157+
"https://crates.io/api/v1/crates/$crate_name" 2>&1); then
158+
159+
# Extract HTTP status code
160+
http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
161+
response=$(echo "$response" | sed 's/HTTPSTATUS:[0-9]*$//')
162+
163+
echo " HTTP status: $http_code" >&2
164+
165+
if [[ "$http_code" == "200" ]] && [[ -n "$response" ]]; then
166+
echo " Successfully fetched crate info" >&2
167+
else
168+
echo " HTTP error $http_code" >&2
169+
return 1
170+
fi
171+
else
172+
echo " Curl failed: " $? >&2
173+
return 1
174+
fi
175+
176+
if [[ -z "$response" ]]; then
177+
echo " Error: Empty response for $crate_name info" >&2
178+
return 1
179+
fi
180+
181+
if ! max_version=$(echo "$response" | grep -o '"max_version":"[^"]*"' | cut -d'"' -f4); then
182+
echo " Error: Failed to extract max_version from response" >&2
183+
echo " Response preview: $(echo "$response" | head -c 200)..." >&2
184+
return 1
185+
fi
186+
187+
if [[ -z "$max_version" ]]; then
188+
echo " Error: Empty max_version extracted" >&2
189+
return 1
190+
fi
191+
192+
echo "$max_version"
193+
return 0
194+
}
195+
196+
# Function to compare versions (returns 0 if only patch differs, 1 if minor/major differs)
197+
compare_versions() {
198+
local local_ver=$1
199+
local published_ver=$2
200+
201+
echo " Comparing versions: local=$local_ver vs published=$published_ver"
202+
203+
# Extract major.minor from both versions
204+
local local_major_minor
205+
local published_major_minor
206+
207+
local_major_minor=$(echo "$local_ver" | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/')
208+
published_major_minor=$(echo "$published_ver" | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/')
209+
210+
echo " Extracted major.minor: local=$local_major_minor vs published=$published_major_minor"
211+
212+
if [[ "$local_major_minor" == "$published_major_minor" ]]; then
213+
echo " Result: Only patch version differs (compatible)"
214+
return 0 # Only patch version differs
215+
else
216+
echo " Result: Major or minor version differs (incompatible)"
217+
return 1 # Major or minor version differs
218+
fi
219+
}
220+
221+
# Run main function with all arguments
222+
main "$@"

0 commit comments

Comments
 (0)