From f25e5a89f00bcecacee4f09901d5cfdc1be341c6 Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Tue, 22 Jul 2025 20:32:02 +0800 Subject: Add CI to check ir module versioning (#7821) --- .github/workflows/ci.yml | 18 +++ .github/workflows/comment-ir-version-check.yml | 73 +++++++++ extras/check-inst-version-changes.sh | 197 +++++++++++++++++++++++++ source/slang/slang-ir.h | 1 + 4 files changed, 289 insertions(+) create mode 100644 .github/workflows/comment-ir-version-check.yml create mode 100755 extras/check-inst-version-changes.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f831415f..c3444f1b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -145,6 +145,24 @@ jobs: if: ${{ matrix.os == 'linux' && matrix.config == 'debug' }} run: ./extras/check-ir-stable-names-gh-actions.sh + - name: Check Version Constants + id: check-ir-versions + if: ${{ matrix.os == 'linux' && matrix.config == 'debug' && github.event_name == 'pull_request' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_EVENT_NAME: ${{ github.event_name }} + GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + GITHUB_BASE_REF: ${{ github.base_ref }} + run: ./extras/check-inst-version-changes.sh + + - name: Upload IR version check results + if: ${{ steps.check-versions.outputs.artifact_created == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: ir-version-check-results + path: ir-version-check-artifact/ + retention-days: 1 + - name: Build Slang if: steps.filter.outputs.should-run == 'true' run: | diff --git a/.github/workflows/comment-ir-version-check.yml b/.github/workflows/comment-ir-version-check.yml new file mode 100644 index 000000000..462e2ec9c --- /dev/null +++ b/.github/workflows/comment-ir-version-check.yml @@ -0,0 +1,73 @@ +name: Comment IR Version Check Results + +on: + workflow_run: + workflows: ["CI"] + types: + - completed + +jobs: + comment: + runs-on: ubuntu-latest + if: github.event.workflow_run.event == 'pull_request' + + steps: + - name: Download artifacts + id: download + uses: actions/github-script@v7 + with: + script: | + const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.event.workflow_run.id }}, + }); + + const matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "ir-version-check-results" + })[0]; + + if (!matchArtifact) { + console.log('No IR version check artifacts found - nothing to comment'); + return false; + } + + const download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + + const fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/ir-version-check-results.zip', Buffer.from(download.data)); + return true; + + - name: Extract artifacts + if: steps.download.outputs.result == 'true' + run: unzip ir-version-check-results.zip + + - name: Read PR number + if: steps.download.outputs.result == 'true' + id: pr + run: | + echo "number=$(cat pr-number.txt)" >> $GITHUB_OUTPUT + + - name: Find existing comment + if: steps.download.outputs.result == 'true' + id: find-comment + uses: peter-evans/find-comment@v3 + with: + token: ${{ secrets.SLANGBOT_PAT }} + issue-number: ${{ steps.pr.outputs.number }} + body-includes: "" + + - name: Create or update comment + if: steps.download.outputs.result == 'true' + uses: peter-evans/create-or-update-comment@v4 + with: + token: ${{ secrets.SLANGBOT_PAT }} + issue-number: ${{ steps.pr.outputs.number }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} + body-path: comment-body.txt + edit-mode: replace diff --git a/extras/check-inst-version-changes.sh b/extras/check-inst-version-changes.sh new file mode 100755 index 000000000..74b851796 --- /dev/null +++ b/extras/check-inst-version-changes.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# Enable debug mode if DEBUG env var is set +DEBUG="${DEBUG:-false}" + +debug_log() { + if [[ "$DEBUG" == "true" ]]; then + echo "[DEBUG] $*" >&2 + fi +} + +# Check if running in GitHub Actions +if [[ -z "${GITHUB_ACTIONS:-}" ]]; then + echo "This script is designed to run in GitHub Actions" + exit 0 +fi + +# Check for required tools +if ! command -v gh &>/dev/null; then + echo "Error: GitHub CLI (gh) is not installed" + exit 1 +fi + +# Verify GitHub authentication +if ! gh auth status &>/dev/null; then + echo "Error: Not authenticated with GitHub CLI" + exit 1 +fi + +# Function to check if module ir version constants were modified +check_module_versions_modified() { + local base_ref="$1" + + # Check if slang-ir.h was modified and if the version constants were changed + if git diff --name-only "$base_ref...HEAD" | grep -q "^source/slang/slang-ir\.h$"; then + # Check if either version constant was modified + if git diff "$base_ref...HEAD" -- source/slang/slang-ir.h | grep -E "^\+.*k_(min|max)SupportedModuleVersion\s*="; then + debug_log "Module version constants were modified" + return 0 + fi + fi + + debug_log "Module version constants were not modified" + return 1 +} + +# Function to check if serialization version was modified +check_serialization_version_modified() { + local base_ref="$1" + + # Check if the serialization version constant was modified + if git diff "$base_ref...HEAD" -- source/slang/slang-serialize-ir.cpp | grep -E "^\+.*kSupportedSerializationVersion\s*="; then + debug_log "Serialization version constant was modified" + return 0 + fi + + debug_log "Serialization version constant was not modified" + return 1 +} + +# Get PR number if this is a pull request +PR_NUMBER="" +if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then + PR_NUMBER="${GITHUB_EVENT_PULL_REQUEST_NUMBER:-${GITHUB_PULL_REQUEST_NUMBER:-}}" + if [[ -z "$PR_NUMBER" ]] && [[ -f "${GITHUB_EVENT_PATH:-}" ]]; then + PR_NUMBER=$(jq -r '.pull_request.number // empty' "$GITHUB_EVENT_PATH" 2>/dev/null || echo "") + fi +fi + +debug_log "Event name: $GITHUB_EVENT_NAME" +debug_log "PR number: ${PR_NUMBER:-}" + +# Get the base ref for comparison +if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then + BASE_REF="origin/${GITHUB_BASE_REF}" + debug_log "Fetching base ref: $GITHUB_BASE_REF" + if ! git fetch origin "$GITHUB_BASE_REF" --depth=1; then + echo "Warning: Failed to fetch base ref, trying without depth limit" + git fetch origin "$GITHUB_BASE_REF" + fi +else + BASE_REF="HEAD^1" +fi + +debug_log "Base ref for comparison: $BASE_REF" + +# Get list of changed files +CHANGED_FILES=$(git diff --name-only "$BASE_REF...HEAD" || echo "") +debug_log "Changed files:" +debug_log "$CHANGED_FILES" + +# Check for changes in IR instruction files +INST_FILES_CHANGED=false +if echo "$CHANGED_FILES" | grep -E "^source/slang/slang-ir-insts(-stable-names)?\.lua$"; then + INST_FILES_CHANGED=true + debug_log "IR instruction files have changed" +fi + +# Check for changes in serialization file +SERIALIZE_CHANGED=false +if echo "$CHANGED_FILES" | grep -q "^source/slang/slang-serialize-ir\.cpp$"; then + SERIALIZE_CHANGED=true + debug_log "Serialization file has changed" +fi + +# Initialize comment body +COMMENT_BODY="" +NEEDS_COMMENT=false + +# Check if we need to add warnings +if [[ "$INST_FILES_CHANGED" == "true" ]]; then + # Check if the version constants have already been updated + if check_module_versions_modified "$BASE_REF"; then + echo "::notice::IR instruction files changed but module version constants were already updated" + else + NEEDS_COMMENT=true + if [[ -n "$COMMENT_BODY" ]]; then + COMMENT_BODY="${COMMENT_BODY} + +" + fi + COMMENT_BODY="${COMMENT_BODY}⚠️ **IR Instruction Files Changed** + +This PR modifies IR instruction definition files. Please review if you need to update the following constants in \`source/slang/slang-ir.h\`: + +- \`k_minSupportedModuleVersion\`: Should be incremented if you're removing instructions or making breaking changes +- \`k_maxSupportedModuleVersion\`: Should be incremented when adding new instructions + +These version numbers help ensure compatibility between different versions of compiled modules." + + echo "::warning::IR instruction files changed - please check if module version constants need updating" + fi +fi + +if [[ "$SERIALIZE_CHANGED" == "true" ]]; then + # Check if the serialization version has already been updated + if check_serialization_version_modified "$BASE_REF"; then + echo "::notice::Serialization code changed but serialization version was already updated" + else + NEEDS_COMMENT=true + if [[ -n "$COMMENT_BODY" ]]; then + COMMENT_BODY="${COMMENT_BODY} + +" + fi + COMMENT_BODY="${COMMENT_BODY}⚠️ **Serialization Code Changed** + +This PR modifies \`source/slang/slang-serialize-ir.cpp\`. Please review if you need to update: + +- \`kSupportedSerializationVersion\`: Should be incremented if you're making backwards-incompatible changes to the serialization format + +This version number helps maintain compatibility when loading serialized IR modules." + + echo "::warning::Serialization code changed - please check if serialization version needs updating" + fi +fi + +# Create artifact directory only if we need to comment +if [[ "$NEEDS_COMMENT" == "true" ]] && [[ -n "$PR_NUMBER" ]]; then + ARTIFACT_DIR="${ARTIFACT_DIR:-ir-version-check-artifact}" + debug_log "Creating artifact directory: $ARTIFACT_DIR" + mkdir -p "$ARTIFACT_DIR" + + # Write artifact files + echo "$PR_NUMBER" >"$ARTIFACT_DIR/pr-number.txt" + + # Write comment body with marker + { + echo "" + echo "$COMMENT_BODY" + } >"$ARTIFACT_DIR/comment-body.txt" + + debug_log "Artifact files created:" + debug_log " pr-number: $PR_NUMBER" + debug_log " comment-body: $(wc -l <"$ARTIFACT_DIR/comment-body.txt") lines" + + # Set output to indicate artifact was created + if [[ -n "${GITHUB_OUTPUT:-}" ]]; then + echo "artifact_created=true" >>"$GITHUB_OUTPUT" + else + echo "::set-output name=artifact_created::true" + fi +else + debug_log "No artifact needed (needs_comment=$NEEDS_COMMENT, pr_number=${PR_NUMBER:-})" + + # Set output to indicate no artifact was created + if [[ -n "${GITHUB_OUTPUT:-}" ]]; then + echo "artifact_created=false" >>"$GITHUB_OUTPUT" + else + echo "::set-output name=artifact_created::false" + fi +fi + +debug_log "Script completed successfully" +exit 0 diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h index 0f4da4f0d..1f6418036 100644 --- a/source/slang/slang-ir.h +++ b/source/slang/slang-ir.h @@ -2409,6 +2409,7 @@ public: // const static UInt k_minSupportedModuleVersion = 1; const static UInt k_maxSupportedModuleVersion = 1; + static_assert(k_minSupportedModuleVersion <= k_maxSupportedModuleVersion); private: friend struct IRSerialReadContext; -- cgit v1.2.3