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
5 changes: 5 additions & 0 deletions .github/workflows/main-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ jobs:
filters: |
packages:
- "packages/**"
- "Scarb.toml"
- "Scarb.lock"
- ".tool-versions"
infra_ci:
- ".github/workflows/**"
Expand Down Expand Up @@ -138,6 +140,9 @@ jobs:
- name: Warm snforge plugin cache
run: snforge --version

- name: Verify workspace compiles
run: scarb build --workspace

test:
name: test (${{ matrix.module }})
needs: setup
Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/pr-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
filters: |
packages:
- "packages/**"
- "Scarb.toml"
- "Scarb.lock"
- ".tool-versions"
packages_review:
- "packages/**"
Expand Down Expand Up @@ -73,6 +75,9 @@ jobs:
- "packages/test_common/**"
tool_versions:
- ".tool-versions"
workspace_manifests:
- "Scarb.toml"
- "Scarb.lock"

- name: Compute test matrix from changed packages
id: compute-matrix
Expand All @@ -86,6 +91,7 @@ jobs:
FILTER_TEST_COMMON: ${{ steps.filter.outputs.test_common }}
FILTER_PRESETS: ${{ steps.filter.outputs.presets }}
FILTER_TOOL_VERSIONS: ${{ steps.filter.outputs.tool_versions }}
FILTER_WORKSPACE_MANIFESTS: ${{ steps.filter.outputs.workspace_manifests }}
run: |
# Determine which group packages need testing based on transitive deps
# interfaces & testing & .tool-versions → ALL
Expand All @@ -103,7 +109,7 @@ jobs:
NEED_UTILITIES="false"
NEED_PRESETS="false"

if [ "$FILTER_INTERFACES" = "true" ] || [ "$FILTER_TESTING" = "true" ] || [ "$FILTER_TOOL_VERSIONS" = "true" ]; then
if [ "$FILTER_INTERFACES" = "true" ] || [ "$FILTER_TESTING" = "true" ] || [ "$FILTER_TOOL_VERSIONS" = "true" ] || [ "$FILTER_WORKSPACE_MANIFESTS" = "true" ]; then
RUN_ALL="true"
fi

Expand Down Expand Up @@ -356,6 +362,9 @@ jobs:
- name: Warm snforge plugin cache
run: snforge --version

- name: Verify workspace compiles
run: scarb build --workspace

test:
name: test (${{ matrix.module }})
needs: [changes, setup]
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ When `update_game()` is called, the token checks if the minter implements `IMeta

The `validate-config` job in CI automatically verifies that the module count matches `codecov.yml`. If they diverge, CI will fail with an actionable error message.

### Adding a New Package or Workspace Dependency

When adding a new group package or changing a workspace-level dependency in the root `Scarb.toml`, update the `packages` path filter in both CI workflows so the change triggers builds and tests. In `pr-ci.yml`, also add the package to the `compute-matrix` dependency graph so transitive consumers are tested.

### Adding a New Module

When adding a new module to a group package, update **both** files:
Expand Down
2 changes: 1 addition & 1 deletion Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ ekubo = { git = "https://github.com/EkuboProtocol/starknet-contracts.git", tag =
starknet.workspace = true
# Group packages
game_components_interfaces = { path = "packages/interfaces" }
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", branch = "next" }
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", rev = "3c5a1ef" }
game_components_embeddable_game_standard = { path = "packages/embeddable_game_standard" }
game_components_metagame = { path = "packages/metagame" }
game_components_economy = { path = "packages/economy" }
Expand Down
2 changes: 1 addition & 1 deletion packages/interfaces/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ edition.workspace = true
[dependencies]
starknet.workspace = true
ekubo.workspace = true
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", branch = "next" }
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", rev = "3c5a1ef" }

[lib]
2 changes: 1 addition & 1 deletion packages/metagame/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ openzeppelin_interfaces.workspace = true
openzeppelin_introspection.workspace = true
game_components_interfaces = { path = "../interfaces" }
game_components_utilities = { path = "../utilities" }
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", branch = "next" }
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", rev = "3c5a1ef" }

[dev-dependencies]
snforge_std.workspace = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ pub mod EntryRequirementComponent {
use core::num::traits::Zero;
use game_components_interfaces::entry_requirement::{IENTRY_REQUIREMENT_ID, IEntryRequirement};
use interfaces::entry_requirement_extension::{
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryRequirementExtensionDispatcher,
IEntryRequirementExtensionDispatcherTrait,
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryValidatorDispatcher, IEntryValidatorDispatcherTrait,
};
use openzeppelin_interfaces::erc721::IERC721_ID;
use openzeppelin_interfaces::introspection::{ISRC5Dispatcher, ISRC5DispatcherTrait};
Expand Down Expand Up @@ -231,7 +230,7 @@ pub mod EntryRequirementComponent {
let display_address: felt252 = config.address.into();
assert!(
src5.supports_interface(IENTRY_REQUIREMENT_EXTENSION_ID),
"EntryRequirement: Extension {} does not support IEntryRequirementExtension",
"EntryRequirement: Extension {} does not support IEntryValidator",
display_address,
);
self.set_extension_address(context_id, config.address);
Expand Down Expand Up @@ -288,7 +287,7 @@ pub mod EntryRequirementComponent {
}

/// Validates entry requirement configuration at creation time.
/// Checks SRC5 interfaces (ERC721 for token, IEntryRequirementExtension for extension).
/// Checks SRC5 interfaces (ERC721 for token, IEntryValidator for extension).
fn assert_valid_entry_requirement(
self: @ComponentState<TContractState>, entry_requirement: EntryRequirement,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

use core::num::traits::Zero;
use interfaces::entry_requirement_extension::{
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryRequirementExtensionDispatcher,
IEntryRequirementExtensionDispatcherTrait,
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryValidatorDispatcher, IEntryValidatorDispatcherTrait,
};
use openzeppelin_interfaces::erc721::{IERC721Dispatcher, IERC721DispatcherTrait, IERC721_ID};
use openzeppelin_interfaces::introspection::{ISRC5Dispatcher, ISRC5DispatcherTrait};
Expand Down Expand Up @@ -159,7 +158,7 @@ pub impl EntryRequirementStoreImpl<T, +Store<T>, +Drop<T>> of EntryRequirementSt
"EntryRequirement: Provided qualification proof is not of type 'Extension'",
),
};
let entry_validator_dispatcher = IEntryRequirementExtensionDispatcher {
let entry_validator_dispatcher = IEntryValidatorDispatcher {
contract_address: extension_config.address,
};
let caller_address = get_caller_address();
Expand Down Expand Up @@ -197,7 +196,7 @@ pub impl EntryRequirementStoreImpl<T, +Store<T>, +Drop<T>> of EntryRequirementSt
let display_address: felt252 = extension_address.into();
assert!(
src5_dispatcher.supports_interface(IENTRY_REQUIREMENT_EXTENSION_ID),
"EntryRequirement: Extension address {} does not support IEntryRequirementExtension interface",
"EntryRequirement: Extension address {} does not support IEntryValidator interface",
display_address,
);
},
Expand All @@ -213,7 +212,7 @@ pub impl EntryRequirementStoreImpl<T, +Store<T>, +Drop<T>> of EntryRequirementSt
match entry_requirement.entry_requirement_type {
EntryRequirementType::extension(extension_config) => {
let extension_address = extension_config.address;
let entry_validator_dispatcher = IEntryRequirementExtensionDispatcher {
let entry_validator_dispatcher = IEntryValidatorDispatcher {
contract_address: extension_address,
};
let display_extension_address: felt252 = extension_address.into();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/// Mock that implements IEntryRequirementExtension with limited entries remaining.
/// Mock that implements IEntryValidator with limited entries remaining.
/// Always accepts entries (valid_entry returns true), entries_left returns Option::Some(5).
#[starknet::contract]
pub mod AcceptingLimitedEntryValidatorMock {
use interfaces::entry_requirement_extension::{
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryRequirementExtension,
};
use interfaces::entry_requirement_extension::{IENTRY_REQUIREMENT_EXTENSION_ID, IEntryValidator};
use openzeppelin_introspection::src5::SRC5Component;
use openzeppelin_introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait;
use starknet::ContractAddress;
Expand Down Expand Up @@ -38,7 +36,7 @@ pub mod AcceptingLimitedEntryValidatorMock {
}

#[abi(embed_v0)]
impl EntryRequirementExtensionImpl of IEntryRequirementExtension<ContractState> {
impl EntryValidatorImpl of IEntryValidator<ContractState> {
fn owner_address(self: @ContractState) -> ContractAddress {
self.owner_address.read()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/// Simple mock that implements IEntryRequirementExtension without using the component.
/// Simple mock that implements IEntryValidator without using the component.
/// Always accepts entries (valid_entry returns true, should_ban returns false).
#[starknet::contract]
pub mod EntryValidatorMock {
use interfaces::entry_requirement_extension::{
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryRequirementExtension,
};
use interfaces::entry_requirement_extension::{IENTRY_REQUIREMENT_EXTENSION_ID, IEntryValidator};
use openzeppelin_introspection::src5::SRC5Component;
use openzeppelin_introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait;
use starknet::ContractAddress;
Expand Down Expand Up @@ -38,7 +36,7 @@ pub mod EntryValidatorMock {
}

#[abi(embed_v0)]
impl EntryRequirementExtensionImpl of IEntryRequirementExtension<ContractState> {
impl EntryValidatorImpl of IEntryValidator<ContractState> {
fn owner_address(self: @ContractState) -> ContractAddress {
self.owner_address.read()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/// Simple mock that implements IEntryRequirementExtension but always rejects entries.
/// Simple mock that implements IEntryValidator but always rejects entries.
#[starknet::contract]
pub mod RejectingEntryValidatorMock {
use interfaces::entry_requirement_extension::{
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryRequirementExtension,
};
use interfaces::entry_requirement_extension::{IENTRY_REQUIREMENT_EXTENSION_ID, IEntryValidator};
use openzeppelin_introspection::src5::SRC5Component;
use openzeppelin_introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait;
use starknet::ContractAddress;
Expand Down Expand Up @@ -37,7 +35,7 @@ pub mod RejectingEntryValidatorMock {
}

#[abi(embed_v0)]
impl EntryRequirementExtensionImpl of IEntryRequirementExtension<ContractState> {
impl EntryValidatorImpl of IEntryValidator<ContractState> {
fn owner_address(self: @ContractState) -> ContractAddress {
self.owner_address.read()
}
Expand Down
2 changes: 1 addition & 1 deletion packages/test_common/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ game_components_interfaces = { path = "../interfaces" }
game_components_embeddable_game_standard = { path = "../embeddable_game_standard" }
game_components_metagame = { path = "../metagame" }
game_components_utilities = { path = "../utilities" }
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", branch = "next" }
interfaces = { git = "https://github.com/Provable-Games/metagame_extensions.git", rev = "3c5a1ef" }

[lib]

Expand Down
8 changes: 3 additions & 5 deletions packages/test_common/src/mocks/mock_entry_validator.cairo
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/// Simple mock that implements IEntryRequirementExtension without using the component.
/// Simple mock that implements IEntryValidator without using the component.
/// Always accepts entries (valid_entry returns true, should_ban returns false).
#[starknet::contract]
pub mod EntryValidatorMock {
use interfaces::entry_requirement_extension::{
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryRequirementExtension,
};
use interfaces::entry_requirement_extension::{IENTRY_REQUIREMENT_EXTENSION_ID, IEntryValidator};
use openzeppelin_introspection::src5::SRC5Component;
use openzeppelin_introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait;
use starknet::ContractAddress;
Expand Down Expand Up @@ -38,7 +36,7 @@ pub mod EntryValidatorMock {
}

#[abi(embed_v0)]
impl EntryRequirementExtensionImpl of IEntryRequirementExtension<ContractState> {
impl EntryValidatorImpl of IEntryValidator<ContractState> {
fn owner_address(self: @ContractState) -> ContractAddress {
self.owner_address.read()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/// Simple mock that implements IEntryRequirementExtension but always rejects entries.
/// Simple mock that implements IEntryValidator but always rejects entries.
#[starknet::contract]
pub mod RejectingEntryValidatorMock {
use interfaces::entry_requirement_extension::{
IENTRY_REQUIREMENT_EXTENSION_ID, IEntryRequirementExtension,
};
use interfaces::entry_requirement_extension::{IENTRY_REQUIREMENT_EXTENSION_ID, IEntryValidator};
use openzeppelin_introspection::src5::SRC5Component;
use openzeppelin_introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait;
use starknet::ContractAddress;
Expand Down Expand Up @@ -37,7 +35,7 @@ pub mod RejectingEntryValidatorMock {
}

#[abi(embed_v0)]
impl EntryRequirementExtensionImpl of IEntryRequirementExtension<ContractState> {
impl EntryValidatorImpl of IEntryValidator<ContractState> {
fn owner_address(self: @ContractState) -> ContractAddress {
self.owner_address.read()
}
Expand Down