diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index da3ab4b..85d9408 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -4,8 +4,6 @@ on: push: branches: [ main ] workflow_dispatch: - schedule: - - cron: '0 0 * * *' # Daily at midnight UTC jobs: check-version: @@ -24,7 +22,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install toml requests + pip install packaging requests toml - name: Check if dependencies changed id: check @@ -33,6 +31,7 @@ jobs: import toml import requests import os + from packaging.version import Version # Read current Cargo.toml with open('Cargo.toml', 'r') as f: @@ -43,41 +42,34 @@ jobs: pyproject = toml.load(f) current_version = pyproject['project']['version'] + cargo_version = cargo_toml['package']['version'] + + if current_version != cargo_version: + raise ValueError( + f"Package versions must match: pyproject.toml={current_version}, " + f"Cargo.toml={cargo_version}" + ) # Get boxcars dependency version boxcars_version = cargo_toml['dependencies']['boxcars'] if isinstance(boxcars_version, dict): boxcars_version = boxcars_version.get('version', '') - # Check latest version on PyPI - try: - response = requests.get('https://pypi.org/pypi/sprocket-rl-parser/json') - if response.status_code == 200: - pypi_data = response.json() - latest_pypi_version = pypi_data['info']['version'] - - # Check if PyPI package has same boxcars version in metadata - # We'll compare versions to see if we need to bump - print(f"Current PyPI version: {latest_pypi_version}") - print(f"Current local version: {current_version}") - print(f"Boxcars dependency: {boxcars_version}") - - # For now, we'll trigger a publish if workflow is manually triggered - # or if it's been a day and there might be updates - should_publish = "true" - - # Calculate new version (bump patch) - parts = latest_pypi_version.split('.') - new_patch = int(parts[2]) + 1 - new_version = f"{parts[0]}.{parts[1]}.{new_patch}" - else: - # Package doesn't exist on PyPI yet - should_publish = "true" - new_version = current_version - except Exception as e: - print(f"Error checking PyPI: {e}") - should_publish = "true" - new_version = current_version + # Only publish a version explicitly committed to both manifests. + response = requests.get( + 'https://pypi.org/pypi/sprocket-rl-parser/json', timeout=15 + ) + response.raise_for_status() + latest_pypi_version = response.json()['info']['version'] + + print(f"Current PyPI version: {latest_pypi_version}") + print(f"Current local version: {current_version}") + print(f"Boxcars dependency: {boxcars_version}") + + should_publish = str( + Version(current_version) > Version(latest_pypi_version) + ).lower() + new_version = current_version # Set outputs with open(os.environ['GITHUB_OUTPUT'], 'a') as f: @@ -124,25 +116,15 @@ jobs: version: "29.x" repo-token: ${{ secrets.GITHUB_TOKEN }} - - name: Update version in pyproject.toml + - name: Verify version in pyproject.toml shell: bash run: | - VERSION="${{ needs.check-version.outputs.new_version }}" - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' "s/^version = .*/version = \"$VERSION\"/" pyproject.toml - else - sed -i "s/^version = .*/version = \"$VERSION\"/" pyproject.toml - fi - - - name: Update version in Cargo.toml + test "$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')" = "${{ needs.check-version.outputs.new_version }}" + + - name: Verify version in Cargo.toml shell: bash run: | - VERSION="${{ needs.check-version.outputs.new_version }}" - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' "s/^version = .*/version = \"$VERSION\"/" Cargo.toml - else - sed -i "s/^version = .*/version = \"$VERSION\"/" Cargo.toml - fi + test "$(python -c 'import tomllib; print(tomllib.load(open("Cargo.toml", "rb"))["package"]["version"])')" = "${{ needs.check-version.outputs.new_version }}" - name: Build wheels uses: PyO3/maturin-action@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..53a345e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: Test + +on: + pull_request: + push: + branches: [main] + +jobs: + cargo-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install Protoc + uses: arduino/setup-protoc@v3 + with: + version: "29.x" + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Run Rust tests + run: cargo test --locked diff --git a/Cargo.lock b/Cargo.lock index 16c9f18..91c7183 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,7 +321,7 @@ checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "sprocket-rl-parser" -version = "1.2.4" +version = "1.3.0" dependencies = [ "boxcars", "pyo3", diff --git a/Cargo.toml b/Cargo.toml index 71c53ad..2e55250 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sprocket-rl-parser" -version = "1.2.4" +version = "1.3.0" edition = "2021" description = "Python bindings for the Rocket League replay parser boxcars." authors = ["Jake Bailey "] @@ -13,6 +13,6 @@ name = "_lib" crate-type = ["cdylib"] [dependencies] -boxcars = "0.11.5" +boxcars = "=0.11.5" serde_json = "1.0.133" pyo3 = { version = "0.22.0", features = ["generate-import-lib"] } diff --git a/pyproject.toml b/pyproject.toml index b67fea7..6eaacc4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "sprocket-rl-parser" -version = "1.2.2" +version = "1.3.0" description = "Rocket League replay parsing and analysis." readme = "README.md" requires-python = ">=3.7" diff --git a/test-files/973E29BA437C1AA2B54BC6AFE28BA0B3.replay b/test-files/973E29BA437C1AA2B54BC6AFE28BA0B3.replay new file mode 100644 index 0000000..5b046e6 Binary files /dev/null and b/test-files/973E29BA437C1AA2B54BC6AFE28BA0B3.replay differ diff --git a/tests/replay_network_regression.rs b/tests/replay_network_regression.rs new file mode 100644 index 0000000..b823ac4 --- /dev/null +++ b/tests/replay_network_regression.rs @@ -0,0 +1,19 @@ +use boxcars::{NetworkParse, ParserBuilder}; + +const ANONYMIZED_NAME_REPLAY: &[u8] = + include_bytes!("../test-files/973E29BA437C1AA2B54BC6AFE28BA0B3.replay"); + +#[test] +fn parses_network_frames_with_anonymized_player_names() { + let replay = ParserBuilder::new(ANONYMIZED_NAME_REPLAY) + .with_network_parse(NetworkParse::IgnoreOnError) + .on_error_check_crc() + .parse() + .expect("replay should parse"); + + let network_frames = replay + .network_frames + .expect("network parsing errors must not be silently downgraded to missing frames"); + + assert_eq!(network_frames.frames.len(), 10_659); +}