Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@
^inst$
^qa$
^venv$
^\.github$


16 changes: 10 additions & 6 deletions .github/workflows/R-CMD-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ on:

jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (R ${{ matrix.config.r }})
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} (R latest)

strategy:
fail-fast: false
matrix:
os: [macOS-latest, ubuntu-latest]
os: [ubuntu-latest, macos-latest]

env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -26,8 +26,7 @@ jobs:

- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
r-version: 'latest'
use-public-rspm: true

- name: Install dependencies
Expand All @@ -37,6 +36,11 @@ jobs:
shell: Rscript {0}

- uses: r-lib/actions/check-r-package@v2
with:
args: '"--no-manual"'
error-on: '"error"'
check-dir: '"check"'


- name: Show testthat output
if: always()
Expand All @@ -47,5 +51,5 @@ jobs:
if: failure()
uses: actions/upload-artifact@v4
with:
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
name: ${{ matrix.os }}-r-latest-results
path: check
70 changes: 49 additions & 21 deletions .github/workflows/move-issues.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Move linked issues through workflow
name: Chagne status of PR linked issues

on:
pull_request:
Expand All @@ -21,20 +21,22 @@ jobs:
github-token: ${{ secrets.ORG_PROJECTS_TOKEN }}
script: |
// === CONFIG ===
const orgLogin = "Seafood-Globalization-Lab"; // hardcoded org
const orgLogin = "Seafood-Globalization-Lab"; // org slug
const projectNumber = 1; // from URL
const fieldName = "Status"; // field in Project
const targetStatus = "🧪 QA / Staging"; // target option
// ==============

const prBody = context.payload.pull_request?.body || "";
const issueRefs = prBody.match(/#\d+/g) || [];
// Match "#123" or "repo#123" or "org/repo#123"
const issueRefs = prBody.match(/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)?#\d+/g) || [];

if (issueRefs.length === 0) {
console.log("No linked issues found in PR body");
console.log("ℹ️ No linked issues found in PR body");
return;
}

// Get project and its fields at ORG level
// Get project and its fields
const { organization } = await github.graphql(`
query($org: String!, $number: Int!) {
organization(login: $org) {
Expand All @@ -55,35 +57,58 @@ jobs:
`, { org: orgLogin, number: projectNumber });

if (!organization || !organization.projectV2) {
throw new Error(`Project ${projectNumber} not found for org ${orgLogin}`);
throw new Error(`Project ${projectNumber} not found for org ${orgLogin}`);
}

const project = organization.projectV2;
const statusField = project.fields.nodes.find(f => f.name === fieldName);
if (!statusField) throw new Error(`Field '${fieldName}' not found`);
if (!statusField) throw new Error(`Field '${fieldName}' not found`);
const option = statusField.options.find(o => o.name === targetStatus);
if (!option) throw new Error(`Option '${targetStatus}' not found`);
if (!option) throw new Error(`❌ Option '${targetStatus}' not found`);

// Process each ref
for (const ref of issueRefs) {
const match = ref.match(/^(?:(?<owner>[^/]+)\/(?<repo>[^#]+))?#(?<num>\d+)$/);
if (!match || !match.groups) {
console.log(`⚠️ Skipping invalid ref '${ref}'`);
continue;
}

for (const issueRef of issueRefs) {
const issueNumber = parseInt(issueRef.replace("#",""));
console.log(`Moving issue #${issueNumber} → ${targetStatus}`);
const owner = match.groups.owner || context.repo.owner;
const repo = match.groups.repo || context.repo.repo;
const issueNumber = parseInt(match.groups.num, 10);

// Get issue node ID
if (isNaN(issueNumber)) {
console.log(`⚠️ Skipping invalid number in ref '${ref}'`);
continue;
}

// Fetch issue or PR
const { repository } = await github.graphql(`
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
issue(number: $number) { id }
issueOrPullRequest(number: $number) {
__typename
... on Issue { id }
}
}
}
`, {
owner: context.repo.owner,
repo: context.repo.repo,
number: issueNumber
});
`, { owner, repo, number: issueNumber });

if (!repository || !repository.issueOrPullRequest) {
console.log(`⚠️ ${owner}/${repo}#${issueNumber} not found, skipping`);
continue;
}

const issueId = repository.issue.id;
if (repository.issueOrPullRequest.__typename !== "Issue") {
console.log(`ℹ️ ${owner}/${repo}#${issueNumber} is a ${repository.issueOrPullRequest.__typename}, skipping`);
continue;
}

const issueId = repository.issueOrPullRequest.id;
console.log(`➡️ Processing ${owner}/${repo}#${issueNumber}`);

// Add to project
// Add to project (idempotent if already present)
const addResp = await github.graphql(`
mutation($projectId: ID!, $contentId: ID!) {
addProjectV2ItemById(input: {projectId: $projectId, contentId: $contentId}) {
Expand All @@ -93,8 +118,9 @@ jobs:
`, { projectId: project.id, contentId: issueId });

const itemId = addResp.addProjectV2ItemById.item.id;
console.log(` ↳ Added/reused project item ${itemId}`);

// Update Status
// Update Status field
await github.graphql(`
mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
updateProjectV2ItemFieldValue(input: {
Expand All @@ -112,4 +138,6 @@ jobs:
fieldId: statusField.id,
optionId: option.id
});

console.log(` ✅ Moved ${owner}/${repo}#${issueNumber} → ${targetStatus}`);
}
10 changes: 2 additions & 8 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,19 @@ Description: ARTIS (Aquatic Resource Trade in Species) is a global model
allocate seafood trade and production data, and to compute consumption
and trade-flow metrics. Designed to support reproducible research and
policy-relevant analysis of seafood systems.
License: Apache License (>= 2.0)
License: Apache License (>= 2.0) | file LICENSE
URL: https://github.com/Seafood-Globalization-Lab/artis-model
BugReports:
https://github.com/Seafood-Globalization-Lab/artis-model/issues
Depends:
R (>= 4.1.0)
Imports:
aws.s3,
cli,
aws.s3,
cli,
countrycode,
data.table,
DBI,
doParallel,
DBI,
doParallel,
dplyr,
foreach,
future,
Expand All @@ -53,17 +49,15 @@ Imports:
magrittr,
parallel,
qs2,
qs2,
readxl,
reticulate,
stringr,
tibble,
tidyr,
qs2,
DBI,
utils
Suggests:
duckdb,
arrow
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.3.2
Loading