From 04b46828c10358e9a81d780859e4e3832705de66 Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Mon, 26 Feb 2024 12:40:01 +0100 Subject: [PATCH 1/2] :bug: Fix generation for f32 and f64 types --- Solana.Unity.Anchor.Test/Resources/Empty.json | 1 + .../Resources/SolChess.json | 642 ++++++++++++++++++ .../Solana.Unity.Anchor.Test.csproj | 6 + Solana.Unity.Anchor.Test/UnitTest1.cs | 32 +- Solana.Unity.Anchor/ClientGenerator.cs | 4 + 5 files changed, 684 insertions(+), 1 deletion(-) create mode 100644 Solana.Unity.Anchor.Test/Resources/Empty.json create mode 100644 Solana.Unity.Anchor.Test/Resources/SolChess.json diff --git a/Solana.Unity.Anchor.Test/Resources/Empty.json b/Solana.Unity.Anchor.Test/Resources/Empty.json new file mode 100644 index 0000000..7d49d6a --- /dev/null +++ b/Solana.Unity.Anchor.Test/Resources/Empty.json @@ -0,0 +1 @@ +{"version":"0.1.0","name":"hello_world","instructions":[{"name":"hello","accounts":[],"args":[]}]} \ No newline at end of file diff --git a/Solana.Unity.Anchor.Test/Resources/SolChess.json b/Solana.Unity.Anchor.Test/Resources/SolChess.json new file mode 100644 index 0000000..5c97545 --- /dev/null +++ b/Solana.Unity.Anchor.Test/Resources/SolChess.json @@ -0,0 +1,642 @@ +{ + "version": "0.1.0", + "name": "sol_chess", + "instructions": [ + { + "name": "initializeUser", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [] + }, + { + "name": "initializeGame", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "game", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "clock", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "wager", + "type": { + "option": "u64" + } + }, + { + "name": "isRated", + "type": "bool" + } + ] + }, + { + "name": "joinGame", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "game", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "color", + "type": { + "defined": "Color" + } + } + ] + }, + { + "name": "movePiece", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "adversaryUser", + "isMut": true, + "isSigner": false + }, + { + "name": "game", + "isMut": true, + "isSigner": false + }, + { + "name": "sessionToken", + "isMut": false, + "isSigner": false, + "isOptional": true + } + ], + "args": [ + { + "name": "from", + "type": { + "defined": "Square" + } + }, + { + "name": "to", + "type": { + "defined": "Square" + } + } + ] + }, + { + "name": "deposit", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "vault", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "withdraw", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "vault", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "leaveGame", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "game", + "isMut": true, + "isSigner": false + } + ], + "args": [] + }, + { + "name": "resign", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "adversaryUser", + "isMut": true, + "isSigner": false + }, + { + "name": "game", + "isMut": true, + "isSigner": false + } + ], + "args": [] + }, + { + "name": "offerDraw", + "accounts": [ + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "user", + "isMut": true, + "isSigner": false + }, + { + "name": "adversaryUser", + "isMut": true, + "isSigner": false + }, + { + "name": "game", + "isMut": true, + "isSigner": false + } + ], + "args": [] + } + ], + "accounts": [ + { + "name": "Game", + "type": { + "kind": "struct", + "fields": [ + { + "name": "board", + "type": { + "defined": "Board" + } + }, + { + "name": "gameState", + "type": { + "defined": "GameState" + } + }, + { + "name": "white", + "type": { + "option": "publicKey" + } + }, + { + "name": "black", + "type": { + "option": "publicKey" + } + }, + { + "name": "enpassant", + "type": { + "option": { + "defined": "Square" + } + } + }, + { + "name": "castlingRight", + "type": { + "defined": "CastlingRight" + } + }, + { + "name": "wager", + "type": { + "option": "u64" + } + }, + { + "name": "timeControl", + "type": "f64" + }, + { + "name": "drawState", + "type": { + "defined": "DrawState" + } + }, + { + "name": "createdAt", + "type": "i64" + }, + { + "name": "isRated", + "type": "bool" + } + ] + } + }, + { + "name": "User", + "type": { + "kind": "struct", + "fields": [ + { + "name": "currentGame", + "type": { + "option": "publicKey" + } + }, + { + "name": "elo", + "type": "u32" + }, + { + "name": "games", + "type": "u64" + }, + { + "name": "balance", + "type": "u64" + } + ] + } + } + ], + "types": [ + { + "name": "Board", + "type": { + "kind": "struct", + "fields": [ + { + "name": "board", + "type": { + "array": [ + { + "array": [ + { + "defined": "Piece" + }, + 8 + ] + }, + 8 + ] + } + } + ] + } + }, + { + "name": "CastlingRight", + "type": { + "kind": "struct", + "fields": [ + { + "name": "whiteKingside", + "type": "bool" + }, + { + "name": "whiteQueenside", + "type": "bool" + }, + { + "name": "blackKingside", + "type": "bool" + }, + { + "name": "blackQueenside", + "type": "bool" + } + ] + } + }, + { + "name": "Square", + "type": { + "kind": "struct", + "fields": [ + { + "name": "rank", + "type": "u8" + }, + { + "name": "file", + "type": "u8" + } + ] + } + }, + { + "name": "TimeControl", + "type": { + "kind": "struct", + "fields": [ + { + "name": "lastMove", + "type": "i64" + }, + { + "name": "whiteTimer", + "type": "i64" + }, + { + "name": "blackTimer", + "type": "i64" + }, + { + "name": "increment", + "type": "i64" + } + ] + } + }, + { + "name": "Color", + "type": { + "kind": "enum", + "variants": [ + { + "name": "White" + }, + { + "name": "Black" + } + ] + } + }, + { + "name": "DrawState", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Neither" + }, + { + "name": "White" + }, + { + "name": "Black" + }, + { + "name": "Draw" + } + ] + } + }, + { + "name": "GameState", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Waiting" + }, + { + "name": "White" + }, + { + "name": "Black" + }, + { + "name": "WhiteWon" + }, + { + "name": "BlackWon" + }, + { + "name": "Draw" + } + ] + } + }, + { + "name": "Piece", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Empty" + }, + { + "name": "BlackPawn" + }, + { + "name": "BlackRook" + }, + { + "name": "BlackKnight" + }, + { + "name": "BlackBishop" + }, + { + "name": "BlackQueen" + }, + { + "name": "BlackKing" + }, + { + "name": "WhitePawn" + }, + { + "name": "WhiteRook" + }, + { + "name": "WhiteKnight" + }, + { + "name": "WhiteBishop" + }, + { + "name": "WhiteQueen" + }, + { + "name": "WhiteKing" + } + ] + } + } + ], + "errors": [ + { + "code": 6000, + "name": "UserAlreadyInGame", + "msg": "User Already In Game" + }, + { + "code": 6001, + "name": "ColorNotAvailable", + "msg": "Color Not Available" + }, + { + "code": 6002, + "name": "InvalidGameState", + "msg": "Invalid Game State" + }, + { + "code": 6003, + "name": "NotUsersTurn", + "msg": "Not User's Turn" + }, + { + "code": 6004, + "name": "InvalidMove", + "msg": "Invalid Move" + }, + { + "code": 6005, + "name": "KingInCheck", + "msg": "King in Check" + }, + { + "code": 6006, + "name": "InsufficientBalance", + "msg": "Insufficient Balance" + }, + { + "code": 6007, + "name": "NotInGame", + "msg": "Not In Game" + }, + { + "code": 6008, + "name": "GameAlreadyStarted", + "msg": "Game Already Started" + }, + { + "code": 6009, + "name": "InvalidAdversaryUserAccount", + "msg": "Invalid Adversary User Account" + }, + { + "code": 6010, + "name": "AlreadyInGame", + "msg": "User Already In Game" + }, + { + "code": 6011, + "name": "AlreadyOfferedDraw", + "msg": "Already Offered Draw" + }, + { + "code": 6012, + "name": "InvalidUser", + "msg": "Invalid User" + } + ], + "metadata": { + "address": "ChessfTT9XpWA9WxrSSLMnCseRqykb9LaMXKMhyWEiR4" + } +} \ No newline at end of file diff --git a/Solana.Unity.Anchor.Test/Solana.Unity.Anchor.Test.csproj b/Solana.Unity.Anchor.Test/Solana.Unity.Anchor.Test.csproj index 66f5453..286245e 100644 --- a/Solana.Unity.Anchor.Test/Solana.Unity.Anchor.Test.csproj +++ b/Solana.Unity.Anchor.Test/Solana.Unity.Anchor.Test.csproj @@ -27,6 +27,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + diff --git a/Solana.Unity.Anchor.Test/UnitTest1.cs b/Solana.Unity.Anchor.Test/UnitTest1.cs index a306a84..2d47241 100644 --- a/Solana.Unity.Anchor.Test/UnitTest1.cs +++ b/Solana.Unity.Anchor.Test/UnitTest1.cs @@ -5,10 +5,25 @@ namespace Solana.Unity.Anchor.Test [TestClass] public class UnitTest1 { + + [TestMethod] + public void TestEmptyIdl() + { + var res = IdlParser.ParseFile("Resources/Empty.json"); + Assert.IsNotNull(res); + + ClientGenerator c = new(); + + c.GenerateSyntaxTree(res); + Assert.IsNotNull(c); + + var code = c.GenerateCode(res); + Assert.IsNotNull(code); + } + [TestMethod] public void TestMethod1() { - //var res = IdlParser.ParseFile("Resources/ChatExample.json"); var res = IdlParser.ParseFile("Resources/seq.json"); Assert.IsNotNull(res); @@ -20,6 +35,21 @@ public void TestMethod1() var code = c.GenerateCode(res); Assert.IsNotNull(code); } + + [TestMethod] + public void TestIdlWithOptional() + { + var res = IdlParser.ParseFile("Resources/SolChess.json"); + Assert.IsNotNull(res); + + ClientGenerator c = new(); + + c.GenerateSyntaxTree(res); + Assert.IsNotNull(c); + + var code = c.GenerateCode(res); + Assert.IsNotNull(code); + } } } diff --git a/Solana.Unity.Anchor/ClientGenerator.cs b/Solana.Unity.Anchor/ClientGenerator.cs index ec23b19..43274e0 100644 --- a/Solana.Unity.Anchor/ClientGenerator.cs +++ b/Solana.Unity.Anchor/ClientGenerator.cs @@ -829,6 +829,8 @@ private IEnumerable GenerateArgSerializationSyntaxList(IIdlType "i32" => (IdentifierName("GetS32"), 4), "u64" => (IdentifierName("GetU64"), 8), "i64" => (IdentifierName("GetS64"), 8), + "f32" => (IdentifierName("GetSingle"), 4), + "f64" => (IdentifierName("GetDouble"), 8), "bool" => (IdentifierName("GetBool"), 1), _ => throw new Exception("Unexpected Type.") }; @@ -1693,6 +1695,8 @@ private SyntaxKind GetTokenForValueType(IdlValueType idlValueType) "i32" => SyntaxKind.IntKeyword, "u64" => SyntaxKind.ULongKeyword, "i64" => SyntaxKind.LongKeyword, + "f32" => SyntaxKind.FloatKeyword, + "f64" => SyntaxKind.DoubleKeyword, "bool" => SyntaxKind.BoolKeyword, _ => throw new Exception("Unexpected Type.") }; From 935f852d54a989408827d024d06cb7f262ca8a45 Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Mon, 26 Feb 2024 12:43:43 +0100 Subject: [PATCH 2/2] :construction_worker: Dump version and add CI/CD publishing --- .github/workflows/publish.yml | 78 ++++++++++++++--------------------- SharedBuildProperties.props | 10 ++--- 2 files changed, 37 insertions(+), 51 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9b2a1c9..6efa81d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,68 +1,54 @@ name: Build, Pack & Publish on: - push: - branches: - - master # Default release branch + release: + types: [published] + workflow_dispatch: jobs: publish: name: build, pack & publish runs-on: ubuntu-latest steps: - name: Get the sources - uses: actions/checkout@v2 - - name: Run the build script - uses: cake-build/cake-action@v1 - with: - script-path: build.cake - target: Pack - cake-bootstrap: true - - name: Publish Solnet.Anchor.Tool on version change - uses: bmresearch/publish-nuget@master + uses: actions/checkout@v4 + - name: Test and Pack + shell: bash + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + run: | + dotnet tool install Cake.Tool --version 1.1.0 + dotnet tool restore + dotnet cake --target=Pack --verbosity=verbose + - name: Publish Solana.Unity.Anchor + uses: Rebel028/publish-nuget@v2.8.0 with: - PROJECT_FILE_PATH: Solnet.Anchor.Tool/Solnet.Anchor.Tool.csproj - PACKAGE_NAME: Solnet.Anchor.Tool + PROJECT_FILE_PATH: Solana.Unity.Anchor/Solana.Unity.Anchor.csproj + PACKAGE_NAME: Solana.Unity.Anchor VERSION_FILE_PATH: SharedBuildProperties.props VERSION_REGEX: ^\s*(.*)<\/Version>\s*$ TAG_FORMAT: v* NUGET_KEY: ${{secrets.NUGET_API_KEY}} + NUGET_SOURCE: https://api.nuget.org/v3/index.json INCLUDE_SYMBOLS: true - - name: Publish Solnet.Anchor.SourceGenerator on version change - uses: bmresearch/publish-nuget@master - id: publish_nuget + - name: Publish Solana.Unity.Anchor.Tool + uses: Rebel028/publish-nuget@v2.8.0 with: - PROJECT_FILE_PATH: Solnet.Anchor.SourceGenerator/Solnet.Anchor.SourceGenerator.csproj - PACKAGE_NAME: Solnet.Anchor.SourceGenerator + PROJECT_FILE_PATH: Solana.Unity.Anchor.Tool/Solana.Unity.Anchor.Tool.csproj + PACKAGE_NAME: Solana.Unity.Anchor.Tool VERSION_FILE_PATH: SharedBuildProperties.props VERSION_REGEX: ^\s*(.*)<\/Version>\s*$ TAG_FORMAT: v* NUGET_KEY: ${{secrets.NUGET_API_KEY}} + NUGET_SOURCE: https://api.nuget.org/v3/index.json INCLUDE_SYMBOLS: true - - name: Build Changelog - id: build_changelog - uses: mikepenz/release-changelog-builder-action@v1 - env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} - - name: Create GitHub Release - id: create_release - uses: actions/create-release@v1 - with: - tag_name: ${{ steps.publish_nuget.outputs.VERSION }} - release_name: ${{ steps.publish_nuget.outputs.VERSION }} - body: ${{ steps.build_changelog.outputs.changelog }} - env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} - - name: Upload release assets - uses: svenstaro/upload-release-action@v2 + - name: Publish Solana.Unity.Anchor.SourceGenerator + uses: Rebel028/publish-nuget@v2.8.0 with: - repo_token: ${{ secrets.ACCESS_TOKEN }} - file: artifacts/Solnet.Anchor.SourceGenerator.dll - tag: ${{ steps.publish_nuget.outputs.VERSION }} - upload_url: ${{ steps.create_release.outputs.upload_url }} - - name: Upload release assets - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.ACCESS_TOKEN }} - file: artifacts/Solnet.Anchor.Tool.dll - tag: ${{ steps.publish_nuget.outputs.VERSION }} - upload_url: ${{ steps.create_release.outputs.upload_url }} + PROJECT_FILE_PATH: Solana.Unity.Anchor.SourceGenerator/Solana.Unity.Anchor.SourceGenerator.csproj + PACKAGE_NAME: Solana.Unity.Anchor.SourceGenerator + VERSION_FILE_PATH: SharedBuildProperties.props + VERSION_REGEX: ^\s*(.*)<\/Version>\s*$ + TAG_FORMAT: v* + NUGET_KEY: ${{secrets.NUGET_API_KEY}} + NUGET_SOURCE: https://api.nuget.org/v3/index.json + INCLUDE_SYMBOLS: true \ No newline at end of file diff --git a/SharedBuildProperties.props b/SharedBuildProperties.props index 340ef95..effd94b 100644 --- a/SharedBuildProperties.props +++ b/SharedBuildProperties.props @@ -2,11 +2,11 @@ xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> Solana.Unity.Anchor - 0.2.9 - Copyright 2022 © Garbles Labs - Garbles Labs - Garbles Labs - https://github.com/garbles-labs/Solana.Unity.Anchor + 0.2.11 + Copyright 2023 © Magicblock + Magicblock + Magicblock + https://github.com/magicblock-labs/Solana.Unity.Anchor latest MIT icon.png