mirror of https://github.com/smithy-lang/smithy-rs
Add semver-checks CI job (#2518)
* Add semver-checks CI job * Add flag to skip generation * Make it possible to suppress semver checks with label * fix GitHub script * Fix but in semver-checks python script * Cleanup debug info * Move to ci-pr
This commit is contained in:
parent
3862ca0a37
commit
187918a0eb
|
@ -107,3 +107,38 @@ jobs:
|
|||
secrets:
|
||||
SMITHY_RS_PULL_REQUEST_CDN_S3_BUCKET_NAME: ${{ secrets.SMITHY_RS_PULL_REQUEST_CDN_S3_BUCKET_NAME }}
|
||||
SMITHY_RS_PULL_REQUEST_CDN_ROLE_ARN: ${{ secrets.SMITHY_RS_PULL_REQUEST_CDN_ROLE_ARN }}
|
||||
|
||||
semver-checks:
|
||||
name: check the semver status of this PR
|
||||
runs-on: smithy_ubuntu-latest_8-core
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
path: smithy-rs
|
||||
ref: ${{ inputs.git_ref }}
|
||||
- name: Get PR info
|
||||
id: check-breaking-label
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const response = await github.rest.pulls.get({
|
||||
pull_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
});
|
||||
const labels = response.data.labels.map(l => l.name);
|
||||
const isBreaking = labels.includes("breaking-change");
|
||||
const data = {
|
||||
labels,
|
||||
isBreaking
|
||||
};
|
||||
console.log("data:", data);
|
||||
return data;
|
||||
- name: Run semver check
|
||||
uses: ./smithy-rs/.github/actions/docker-build
|
||||
with:
|
||||
action: check-semver
|
||||
action-arguments: ${{ github.event.pull_request.base.sha }} ${{ fromJSON(steps.check-breaking-label.outputs.result).isBreaking }}
|
||||
- name: print help message
|
||||
if: failure()
|
||||
run: echo "::error::This pull request contains breaking changes. Please add the `breaking-changes` label and a changelog entry"
|
||||
|
|
|
@ -159,6 +159,8 @@ jobs:
|
|||
with:
|
||||
action: ${{ matrix.test.action }}
|
||||
|
||||
|
||||
|
||||
test-rust-windows:
|
||||
name: Rust Tests on Windows
|
||||
runs-on: windows-latest
|
||||
|
|
4
ci.mk
4
ci.mk
|
@ -120,6 +120,10 @@ generate-codegen-diff:
|
|||
check-deterministic-codegen:
|
||||
$(CI_ACTION) $@ $(ARGS)
|
||||
|
||||
.PHONY: check-semver
|
||||
check-semver:
|
||||
$(CI_ACTION) $@ $(ARGS)
|
||||
|
||||
.PHONY: generate-smithy-rs-release
|
||||
generate-smithy-rs-release:
|
||||
$(CI_ACTION) $@ $(ARGS)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
set -eux
|
||||
cd smithy-rs
|
||||
|
||||
if [[ $# -gt 2 ]]; then
|
||||
echo "Usage: check-semver <base-revision> <warn-on-failure (true/false)>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Override version commit hash to prevent unnecessary diffs
|
||||
export SMITHY_RS_VERSION_COMMIT_HASH_OVERRIDE=ci
|
||||
base_revision="$1"
|
||||
warn_on_failure="$2"
|
||||
if [[ $warn_on_failure == "true" ]]
|
||||
then
|
||||
./tools/ci-scripts/codegen-diff/semver-checks.py . "${base_revision}" || echo "allowing failure"
|
||||
else
|
||||
./tools/ci-scripts/codegen-diff/semver-checks.py . "${base_revision}"
|
||||
fi
|
|
@ -3,19 +3,18 @@
|
|||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import sys
|
||||
import os
|
||||
from diff_lib import get_cmd_output, generate_and_commit_generated_code
|
||||
import sys
|
||||
|
||||
from diff_lib import get_cmd_output, checkout_commit_and_generate
|
||||
|
||||
|
||||
def main():
|
||||
repository_root = sys.argv[1]
|
||||
os.chdir(repository_root)
|
||||
(_, head_commit_sha, _) = get_cmd_output("git rev-parse HEAD")
|
||||
get_cmd_output("git checkout -B once")
|
||||
generate_and_commit_generated_code(head_commit_sha, targets=['aws:sdk'])
|
||||
get_cmd_output(f"git checkout {head_commit_sha}")
|
||||
get_cmd_output("git checkout -B twice")
|
||||
generate_and_commit_generated_code(head_commit_sha, targets=['aws:sdk'])
|
||||
checkout_commit_and_generate(head_commit_sha, targets=['aws:sdk'], branch_name='once')
|
||||
checkout_commit_and_generate(head_commit_sha, targets=['aws:sdk'], branch_name='twice')
|
||||
get_cmd_output('git diff once..twice --exit-code')
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import os
|
|||
import sys
|
||||
|
||||
from diff_lib import eprint, run, get_cmd_status, get_cmd_output, generate_and_commit_generated_code, make_diffs, \
|
||||
write_to_file, HEAD_BRANCH_NAME, BASE_BRANCH_NAME, OUTPUT_PATH
|
||||
write_to_file, HEAD_BRANCH_NAME, BASE_BRANCH_NAME, OUTPUT_PATH, running_in_docker_build
|
||||
|
||||
|
||||
# This script can be run and tested locally. To do so, you should check out
|
||||
|
@ -32,8 +32,6 @@ from diff_lib import eprint, run, get_cmd_status, get_cmd_output, generate_and_c
|
|||
# ```
|
||||
# Make sure the local version matches the version referenced from the GitHub Actions workflow.
|
||||
|
||||
def running_in_docker_build():
|
||||
return os.environ.get("SMITHY_RS_DOCKER_BUILD_IMAGE") == "1"
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -20,6 +20,21 @@ target_codegen_server = 'codegen-server-test'
|
|||
target_aws_sdk = 'aws:sdk'
|
||||
|
||||
|
||||
def running_in_docker_build():
|
||||
return os.environ.get("SMITHY_RS_DOCKER_BUILD_IMAGE") == "1"
|
||||
|
||||
|
||||
def checkout_commit_and_generate(revision_sha, branch_name, targets=None):
|
||||
if running_in_docker_build():
|
||||
eprint(f"Fetching base revision {revision_sha} from GitHub...")
|
||||
run(f"git fetch --no-tags --progress --no-recurse-submodules --depth=1 origin {revision_sha}")
|
||||
|
||||
# Generate code for HEAD
|
||||
eprint(f"Creating temporary branch {branch_name} with generated code for {revision_sha}")
|
||||
run(f"git checkout {revision_sha} -B {branch_name}")
|
||||
generate_and_commit_generated_code(revision_sha, targets)
|
||||
|
||||
|
||||
def generate_and_commit_generated_code(revision_sha, targets=None):
|
||||
targets = targets or [target_codegen_client, target_codegen_server, target_aws_sdk]
|
||||
# Clean the build artifacts before continuing
|
||||
|
@ -170,12 +185,14 @@ def run(command, shell=False, check=True):
|
|||
|
||||
|
||||
# Returns (status, stdout, stderr) from a shell command
|
||||
def get_cmd_output(command, cwd=None, check=True, **kwargs):
|
||||
def get_cmd_output(command, cwd=None, check=True, quiet=False, **kwargs):
|
||||
if isinstance(command, str):
|
||||
eprint(f"running {command}")
|
||||
if not quiet:
|
||||
eprint(f"running {command}")
|
||||
command = shlex.split(command)
|
||||
else:
|
||||
eprint(f"running {' '.join(command)}")
|
||||
if not quiet:
|
||||
eprint(f"running {' '.join(command)}")
|
||||
|
||||
result = subprocess.run(
|
||||
command,
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import sys
|
||||
import os
|
||||
from diff_lib import get_cmd_output, get_cmd_status, eprint, running_in_docker_build, checkout_commit_and_generate, \
|
||||
OUTPUT_PATH
|
||||
|
||||
|
||||
CURRENT_BRANCH = 'current'
|
||||
BASE_BRANCH = 'base'
|
||||
# This script runs `cargo semver-checks` against a previous version of codegen
|
||||
def main(skip_generation=False):
|
||||
if len(sys.argv) != 3:
|
||||
eprint("Usage: semver-checks.py <repository root> <base commit sha>")
|
||||
sys.exit(1)
|
||||
|
||||
repository_root = sys.argv[1]
|
||||
base_commit_sha = sys.argv[2]
|
||||
os.chdir(repository_root)
|
||||
(_, head_commit_sha, _) = get_cmd_output("git rev-parse HEAD")
|
||||
|
||||
# Make sure the working tree is clean
|
||||
if get_cmd_status("git diff --quiet") != 0:
|
||||
eprint("working tree is not clean. aborting")
|
||||
sys.exit(1)
|
||||
|
||||
if not skip_generation:
|
||||
checkout_commit_and_generate(head_commit_sha, CURRENT_BRANCH, targets=['aws:sdk'])
|
||||
checkout_commit_and_generate(base_commit_sha, BASE_BRANCH, targets=['aws:sdk'])
|
||||
get_cmd_output(f'git checkout {CURRENT_BRANCH}')
|
||||
sdk_directory = os.path.join(OUTPUT_PATH, 'aws-sdk', 'sdk')
|
||||
os.chdir(sdk_directory)
|
||||
|
||||
failed = False
|
||||
for path in os.listdir():
|
||||
eprint(f'checking {path}...', end='')
|
||||
if get_cmd_status(f'git cat-file -e base:{sdk_directory}/{path}/Cargo.toml') == 0:
|
||||
(status, out, err) = get_cmd_output(f'cargo semver-checks check-release '
|
||||
f'--baseline-rev {BASE_BRANCH} '
|
||||
# in order to get semver-checks to work with publish-false crates, need to specify
|
||||
# package and manifest path explicitly
|
||||
f'--manifest-path {path}/Cargo.toml '
|
||||
f'-p {path} '
|
||||
f'--release-type patch', check=False, quiet=True)
|
||||
if status == 0:
|
||||
eprint('ok!')
|
||||
else:
|
||||
failed = True
|
||||
eprint('failed!')
|
||||
if out:
|
||||
eprint(out)
|
||||
eprint(err)
|
||||
else:
|
||||
eprint(f'skipping {path} because it does not exist in base')
|
||||
if failed:
|
||||
eprint('One or more crates failed semver checks!')
|
||||
exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
skip_generation = bool(os.environ.get('SKIP_GENERATION') or False)
|
||||
main(skip_generation=skip_generation)
|
Loading…
Reference in New Issue