Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 38 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,68 @@ on:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
R-CMD-check:
runs-on: ${{ matrix.os }}
name: R-CMD-check (${{ matrix.os }}, R ${{ matrix.r }})
env:
PAK_FORCE_SOURCE_INSTALL: true
PAK_IGNORE_PLATFORM: true
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: ubuntu-latest
r: release
- os: macos-latest
r: release
- os: windows-latest
r: release
- os: ubuntu-latest
r: devel
- os: ubuntu-latest
Comment on lines +26 to +35
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The matrix includes three entries with r: release (ubuntu, macos, windows) which are redundant. The matrix configuration can be simplified by using a cross-product of os and r arrays with exclude rules if needed, rather than repeating r: release three times.

Suggested change
include:
- os: ubuntu-latest
r: release
- os: macos-latest
r: release
- os: windows-latest
r: release
- os: ubuntu-latest
r: devel
- os: ubuntu-latest
os: [ubuntu-latest, macos-latest, windows-latest]
r: [release, devel, oldrel-1]
exclude:
- os: macos-latest
r: devel
- os: macos-latest
r: oldrel-1
- os: windows-latest
r: devel
- os: windows-latest

Copilot uses AI. Check for mistakes.
r: oldrel-1

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable


- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: "src/rust -> target"
shared-key: "rust-${{ matrix.os }}"

- name: Set up R
uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.r }}
use-public-rspm: true


- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev libharfbuzz-dev libfribidi-dev

- name: Install dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck, any::roxygen2
needs: check
continue-on-error: true
id: install-deps

- name: Retry Install dependencies
if: steps.install-deps.outcome == 'failure'
uses: r-lib/actions/setup-r-dependencies@v2
Expand All @@ -53,4 +84,5 @@ jobs:
uses: r-lib/actions/check-r-package@v2
with:
error-on: '"error"'

upload-snapshots: true
args: 'c("--no-manual", "--as-cran")'
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The args parameter uses single quotes around the outer string and double quotes around inner values: 'c("--no-manual", "--as-cran")'. This will be interpreted as an R expression, which is correct, but the syntax could be clearer. Consider using c("--no-manual", "--as-cran") without outer quotes if the action supports it, or document why the outer quotes are necessary.

Suggested change
args: 'c("--no-manual", "--as-cran")'
args: --no-manual --as-cran

Copilot uses AI. Check for mistakes.
25 changes: 20 additions & 5 deletions .github/workflows/pkgdown.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ on:
types: [published]
workflow_dispatch:

name: pkgdown.yaml
name: pkgdown

permissions: read-all

concurrency:
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concurrency group logic pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} will produce pkgdown-true for all non-pull_request events, which means all pushes to main, releases, and manual dispatches will share the same concurrency group. This could cause unintended cancellations. Consider using a more specific group identifier like pkgdown-${{ github.event_name == 'pull_request' && github.run_id || github.ref }} to properly separate different branches/events.

Suggested change
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
group: pkgdown-${{ github.event_name == 'pull_request' && github.run_id || github.ref }}

Copilot uses AI. Check for mistakes.
cancel-in-progress: true

jobs:
pkgdown:
runs-on: ubuntu-latest
# Only restrict concurrency for non-PR jobs
concurrency:
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
env:
PAK_FORCE_SOURCE_INSTALL: true
PAK_IGNORE_PLATFORM: true
Expand All @@ -27,12 +28,26 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: "src/rust -> target"
shared-key: "rust-ubuntu"

- uses: r-lib/actions/setup-pandoc@v2

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev libharfbuzz-dev libfribidi-dev

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::pkgdown, local::.
Expand All @@ -44,7 +59,7 @@ jobs:

- name: Deploy to GitHub pages 🚀
if: github.event_name != 'pull_request'
uses: JamesIves/github-pages-deploy-action@v4.5.0
uses: JamesIves/github-pages-deploy-action@v4.6.8
with:
clean: false
branch: gh-pages
Expand Down
129 changes: 129 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Release

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g., v3.0.6)"
required: false
type: string
Comment on lines +7 to +11
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow has a workflow_dispatch input for tag but this input is never used in the workflow. If manual dispatch is intended to support custom tags, the workflow should use inputs.tag somewhere, or if not needed, the input should be removed to avoid confusion.

Suggested change
inputs:
tag:
description: "Release tag (e.g., v3.0.6)"
required: false
type: string

Copilot uses AI. Check for mistakes.

jobs:
validate:
name: Validate Release
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4

- name: Extract version from DESCRIPTION
id: version
run: |
VERSION=$(grep "^Version:" DESCRIPTION | sed 's/Version: //')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Package version: $VERSION"

- name: Validate tag matches version
if: github.event_name == 'release'
run: |
TAG="${{ github.ref_name }}"
VERSION="${{ steps.version.outputs.version }}"
if [[ "$TAG" != "v$VERSION" && "$TAG" != "$VERSION" ]]; then
echo "::error::Tag ($TAG) does not match package version (v$VERSION)"
exit 1
fi
Comment on lines +29 to +37
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tag validation only runs when github.event_name == 'release' but not for manual workflow_dispatch events. If a user manually triggers this workflow, the validation step will be skipped entirely. Consider whether validation should also run for manual dispatches, or if the manual dispatch should be removed if not fully supported.

Copilot uses AI. Check for mistakes.

build-binaries:
name: Build (${{ matrix.os }})
needs: validate
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
r: release
- os: macos-latest
r: release
- os: windows-latest
r: release
env:
PAK_FORCE_SOURCE_INSTALL: true
PAK_IGNORE_PLATFORM: true
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}

steps:
- uses: actions/checkout@v4

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: "src/rust -> target"
shared-key: "rust-${{ matrix.os }}"

- name: Set up R
uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.r }}
use-public-rspm: true

- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev libharfbuzz-dev libfribidi-dev

- name: Install dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check

- name: Build source package (Linux only)
if: runner.os == 'Linux'
run: |
R CMD build .
mkdir -p dist
mv Pmetrics_*.tar.gz dist/

- name: Build binary package
shell: Rscript {0}
run: |
dir.create("dist", showWarnings = FALSE)
pkg <- pkgbuild::build(binary = TRUE, dest_path = "dist")
message("Built: ", pkg)

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: pmetrics-${{ matrix.os }}
path: dist/*
retention-days: 7

upload-release-assets:
name: Upload Release Assets
needs: build-binaries
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true

- name: List artifacts
run: ls -la artifacts/

- name: Upload to release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
86 changes: 86 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Rust CI

on:
push:
branches: [main]
paths:
- "src/rust/**"
- "Cargo.toml"
- ".github/workflows/rust.yml"
pull_request:
branches: [main]
paths:
- "src/rust/**"
Comment on lines +7 to +13
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow paths filter should also include "src/rust/Cargo.lock" to trigger on dependency updates. Lock file changes indicate dependency version changes that should be validated by CI.

Suggested change
- "src/rust/**"
- "Cargo.toml"
- ".github/workflows/rust.yml"
pull_request:
branches: [main]
paths:
- "src/rust/**"
- "src/rust/**"
- "src/rust/Cargo.lock"
- "Cargo.toml"
- ".github/workflows/rust.yml"
pull_request:
branches: [main]
paths:
- "src/rust/**"
- "src/rust/Cargo.lock"

Copilot uses AI. Check for mistakes.
- "Cargo.toml"
Comment on lines +6 to +14
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow paths filter includes the root Cargo.toml but not src/rust/Cargo.toml. While changes to the root workspace manifest should trigger the workflow, direct changes to src/rust/Cargo.toml (dependencies, package metadata, etc.) would not trigger this workflow. Consider adding "src/rust/Cargo.toml" to the paths list.

Copilot uses AI. Check for mistakes.
- ".github/workflows/rust.yml"
workflow_dispatch:

concurrency:
group: rust-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always

jobs:
fmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fmt job does not utilize caching like the clippy, test, and build jobs do. While formatting is typically fast, adding Rust cache here would improve consistency and could provide minor performance benefits, especially if rustfmt needs to compile any dependencies.

Suggested change
components: rustfmt
components: rustfmt
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: "src/rust -> target"

Copilot uses AI. Check for mistakes.
- name: Check formatting
run: cargo fmt --manifest-path src/rust/Cargo.toml --all -- --check

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: "src/rust -> target"
- name: Run Clippy
run: cargo clippy --manifest-path src/rust/Cargo.toml --all-targets -- -D warnings

test:
name: Rust Tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: "src/rust -> target"
shared-key: "rust-${{ matrix.os }}"
- name: Run tests
run: cargo test --manifest-path src/rust/Cargo.toml --all

build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: "src/rust -> target"
shared-key: "rust-${{ matrix.os }}"
- name: Build
run: cargo build --manifest-path src/rust/Cargo.toml --release
3 changes: 1 addition & 2 deletions src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ fn simulate_all(
rows.into_dataframe().unwrap()
}


/// Fits the model at the given path to the data at the given path using the provided parameters.
/// @param model_path Path to the compiled model file.
/// @param data Path to the data file.
Expand Down Expand Up @@ -307,4 +306,4 @@ extendr_module! {
// To generate the exported function in R, run the following command:
// rextendr::document()
// Optional: reload Pmetrics
// devtools::load_all()
// devtools::load_all()
Loading