name: "Ruby: Build" on: push: paths: - "ruby/**" - .github/workflows/ruby-build.yml - .github/actions/fetch-codeql/action.yml - codeql-workspace.yml - "shared/tree-sitter-extractor/**" branches: - main - "rc/*" pull_request: paths: - "ruby/**" - .github/workflows/ruby-build.yml - .github/actions/fetch-codeql/action.yml - codeql-workspace.yml - "shared/tree-sitter-extractor/**" branches: - main - "rc/*" workflow_dispatch: inputs: tag: description: "Version tag to create" required: false env: CARGO_TERM_COLOR: always defaults: run: working-directory: ruby permissions: contents: read jobs: build: strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v5 - name: Install GNU tar if: runner.os == 'macOS' run: | brew install gnu-tar echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH - name: Prepare Windows if: runner.os == 'Windows' shell: powershell run: | git config --global core.longpaths true - uses: ./.github/actions/os-version id: os_version - name: Cache entire extractor uses: actions/cache@v3 id: cache-extractor with: path: | target/release/codeql-extractor-ruby target/release/codeql-extractor-ruby.exe ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ruby/extractor/**/*.rs') }} - uses: actions/cache@v3 if: steps.cache-extractor.outputs.cache-hit != 'true' with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-rust-cargo-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/**/Cargo.lock') }} - name: Check formatting if: steps.cache-extractor.outputs.cache-hit != 'true' run: cd extractor && cargo fmt -- --check - name: Build if: steps.cache-extractor.outputs.cache-hit != 'true' run: cd extractor && cargo build --verbose - name: Run tests if: steps.cache-extractor.outputs.cache-hit != 'true' run: cd extractor && cargo test --verbose - name: Release build if: steps.cache-extractor.outputs.cache-hit != 'true' run: cd extractor && cargo build --release - name: Generate dbscheme if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}} run: ../target/release/codeql-extractor-ruby generate --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll - uses: actions/upload-artifact@v4 if: ${{ matrix.os == 'ubuntu-latest' }} with: name: ruby.dbscheme path: ruby/ql/lib/ruby.dbscheme - uses: actions/upload-artifact@v4 if: ${{ matrix.os == 'ubuntu-latest' }} with: name: TreeSitter.qll path: ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll - uses: actions/upload-artifact@v4 with: name: extractor-${{ matrix.os }} path: | target/release/codeql-extractor-ruby target/release/codeql-extractor-ruby.exe retention-days: 1 compile-queries: if: github.repository_owner == 'github' runs-on: ubuntu-latest-xl steps: - uses: actions/checkout@v5 - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql - name: Cache compilation cache id: query-cache uses: ./.github/actions/cache-query-compilation with: key: ruby-build - name: Build Query Pack run: | PACKS=${{ runner.temp }}/query-packs rm -rf $PACKS codeql pack create ../misc/suite-helpers --output "$PACKS" codeql pack create ../shared/regex --output "$PACKS" codeql pack create ../shared/ssa --output "$PACKS" codeql pack create ../shared/tutorial --output "$PACKS" codeql pack create ql/lib --output "$PACKS" codeql pack create -j0 ql/src --output "$PACKS" --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" PACK_FOLDER=$(readlink -f "$PACKS"/codeql/ruby-queries/*) codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src (cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;) - uses: actions/upload-artifact@v4 with: name: codeql-ruby-queries path: | ${{ runner.temp }}/query-packs/* retention-days: 1 include-hidden-files: true package: runs-on: ubuntu-latest needs: [build, compile-queries] steps: - uses: actions/checkout@v5 - uses: actions/download-artifact@v4 with: name: ruby.dbscheme path: ruby/ruby - uses: actions/download-artifact@v4 with: name: extractor-ubuntu-latest path: ruby/linux64 - uses: actions/download-artifact@v4 with: name: extractor-windows-latest path: ruby/win64 - uses: actions/download-artifact@v4 with: name: extractor-macos-latest path: ruby/osx64 - run: | mkdir -p ruby cp -r codeql-extractor.yml tools ql/lib/ruby.dbscheme.stats ruby/ mkdir -p ruby/tools/{linux64,osx64,win64} cp linux64/codeql-extractor-ruby ruby/tools/linux64/extractor cp osx64/codeql-extractor-ruby ruby/tools/osx64/extractor cp win64/codeql-extractor-ruby.exe ruby/tools/win64/extractor.exe chmod +x ruby/tools/{linux64,osx64}/extractor zip -rq codeql-ruby.zip ruby - uses: actions/upload-artifact@v4 with: name: codeql-ruby-pack path: ruby/codeql-ruby.zip retention-days: 1 include-hidden-files: true - uses: actions/download-artifact@v4 with: name: codeql-ruby-queries path: ruby/qlpacks - run: | echo '{ "provide": [ "ruby/codeql-extractor.yml", "qlpacks/*/*/*/qlpack.yml" ] }' > .codeqlmanifest.json zip -rq codeql-ruby-bundle.zip .codeqlmanifest.json ruby qlpacks - uses: actions/upload-artifact@v4 with: name: codeql-ruby-bundle path: ruby/codeql-ruby-bundle.zip retention-days: 1 include-hidden-files: true test: defaults: run: working-directory: ${{ github.workspace }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} needs: [package] steps: - uses: actions/checkout@v5 - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql - name: Download Ruby bundle uses: actions/download-artifact@v4 with: name: codeql-ruby-bundle path: ${{ runner.temp }} - name: Unzip Ruby bundle shell: bash run: unzip -q -d "${{ runner.temp }}/ruby-bundle" "${{ runner.temp }}/codeql-ruby-bundle.zip" - name: Run QL test shell: bash run: | codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" ruby/ql/test/library-tests/ast/constants/ - name: Create database shell: bash run: | codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database - name: Analyze database shell: bash run: | codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls