Skip to content

Transition to multi-package repository #126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 18, 2025

Conversation

frobijn
Copy link

@frobijn frobijn commented Feb 18, 2025

Description

Do not merge this PR!

It is the first step towards a multi-package repository. The PR is to make sure we're on the right track.
(Attempt 2 to trigger the pipeline again)

Transition of this Github repository into a repository for multiple NuGet packages/class libraries that collectively are the nanoFramework.Device.Can implementation in the near future.

Most work is done to achieve the correct build infrastructure:

  • .editorconfig
  • Copied and modified the azure-pipelines.yaml from the nanoFramework.m2mqtt repository
  • Provision in yaml/nuspec to create 4 NuGet packages (Esp32 and Mcp2515 commented out in yaml):
    • nanoFramework.Device.Can.Core
    • nanoFramework.Device.Can.Esp32
    • nanoFramework.Device.Can.Mcp2515
    • nanoFramework.Device.Can.Stm32
  • Single Visual Studio solution, single version.json for all libraries/packages.
  • One project per package/library. The device dependent libraries (Esp32, Mcp2515, Stm32) have a direct dependency on the Core library. The corresponding NuGet packages depend on the Core NuGet package of the same version.
  • The solution has an additional configuration GenerateStubs - see Stub-generation.md
  • Updated README.md file

The library code in this PR is not yet up to snuff:

  • The nanoFramework.Device.Can.Core project contains a complete copy of the current nanoFramework.Device.Can library. The AssemblyNativeVersion attribute is removed for normal builds. In a subsequent PR the Stm32-specific code will be removed and optionally replaced by abstract base classes or interfaces.

  • The nanoFramework.Device.Can.Stm32 project contains a complete copy of the current nanoFramework.Device.Can library. The version in AssemblyNativeVersion is changed to an arbitrary value. In a subsequent PR only the Stm32-specific code will be retained as an implementation of the classes and interfaces from the nanoFramework.Device.Can.Core library.

  • The nanoFramework.Device.Can.Esp32 and nanoFramework.Device.Can.Mcp2515 projects are empty except for the assembly properties.

The subsequent PR that contains the correct versions of nanoFramework.Device.Can.Core and nanoFramework.Device.Can.Stm32 will also require a PR for the nf-interpreter repository as the stubs for the native components change. After the PR for both repositories are accepted and merged, the current nanoFramework.Device.Can NuGet package can be marked as deprecated.

Motivation and Context

The conclusion of the discussion on the related PR.

How Has This Been Tested?

  • The solution can be built (ignore all warnings)
  • The NuGet packages can be created and installed.

I have no idea how to test the Azure pipeline.

Types of changes

  • Improvement (non-breaking change that improves a feature, code or algorithm)
  • Bug fix (non-breaking change which fixes an issue with code or algorithm)
  • New feature (non-breaking change which adds functionality to code)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Config and build (change in the configuration and build system, has no impact on code or features)
  • Dependencies (update dependencies and changes associated, has no impact on code or features)
  • Unit Tests (add new Unit Test(s) or improved existing one(s), has no impact on code or features)
  • Documentation (changes or updates in the documentation, has no impact on code or features)

Checklist:

  • My code follows the code style of this project (only if there are changes in source code).
  • My changes require an update to the documentation (there are changes that require the docs website to be updated).
  • I have updated the documentation accordingly (the changes require an update on the docs in this repo).
  • I have read the CONTRIBUTING document.
  • I have tested everything locally and all new and existing tests passed (only if there are changes in source code).
  • I have added new tests to cover my changes.

Summary by CodeRabbit

  • Chores
    • Enhanced release notes to display additional package options.
    • Refined build and release workflows with improved configuration settings and version-triggered steps.
    • Introduced dependency lock files for multiple projects to strengthen version control and ensure reliable package management.

Copy link

coderabbitai bot commented Feb 18, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • nanoFramework.Device.Can.Core.nuspec is excluded by none and included by none

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The pull request updates several configuration files and introduces new dependency lock files. The changelog configuration now lists two NuGet package links instead of one. GitHub Actions workflows are modified by adding a solution parameter and updating formatting. The Azure Pipelines configuration is restructured with new jobs for building libraries, updating dependents, and reporting build failures based on version tag conditions. Additionally, new packages.lock.json files are added to multiple projects, specifying dependency versions and integrity details.

Changes

File(s) Summary
.github/.changelog-config.json Updated the changelog template to list two NuGet package links: nanoFramework.Devices.Can.Core and nanoFramework.Device.Can.Stm32 instead of a single package link.
.github/workflows/pr-checks.yml
.github/workflows/update-dependencies.yml
Added a solution parameter to the check_package_lock job and updated the format of the solutionsToCheck parameter to a multi-line string format in GitHub workflows.
azure-pipelines.yml Introduced new jobs: Build_Library, Update_Dependents, and Report_Build_Failure; restructured the pipeline to trigger builds based on version tagging and condition checks.
nanoFramework.Device.Can.Esp32/packages.lock.json
nanoFramework.Device.Can.Mcp2515/packages.lock.json
nanoFramework.Device.Can.Stm32/packages.lock.json
Added new lock files specifying dependencies and version details for each project, including nanoFramework.CoreLibrary, nanoFramework.Runtime.Events, and Nerdbank.GitVersioning (with a nested dependency in the STM32 project).

Sequence Diagram(s)

sequenceDiagram
    participant VCS as Version Control
    participant BP as Build Pipeline
    participant BL as Build_Library Job
    participant UD as Update_Dependents Job
    participant RB as Report_Build_Failure Job

    VCS->>BP: Trigger build (commit or tag push)
    alt Branch without version tag
      BP->>BL: Run Build_Library job
    else Version tag detected
      BP->>UD: Run Update_Dependents job
    end
    BP->>RB: Evaluate job outcomes
    RB->>BP: Report build failure if any job fails
Loading

Possibly related PRs

Suggested labels

Type: dependencies, CI: Publish Release


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
azure-pipelines.yml (6)

20-23: Tag Trigger Configuration & Trailing Whitespace
The new tags block (lines 20–23) correctly enables trigger builds from version tags; however, YAMLlint has flagged trailing spaces (e.g., on line 21). Please remove any trailing whitespace to ensure clean formatting.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 21-21: trailing spaces

(trailing-spaces)


43-51: Build_Library Job: Indentation Adjustment
The Build_Library job definition (starting at line 43) is not indented as expected under the jobs: key. It should be indented (typically 2 spaces) for proper YAML hierarchy. Please adjust the indentation.
Proposed diff:

-jobs:
-##############################
-   - job: Build_Library
+jobs:
+  ##############################
+  - job: Build_Library
🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 43-43: wrong indentation: expected 2 but found 0

(indentation)


55-63: Variable Definition: Remove Trailing Spaces
In the Build_Library job variables block (lines 55–63), YAMLlint has flagged trailing spaces (e.g., on line 58). Please remove any extraneous whitespace to maintain consistency and avoid potential parsing issues.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 58-58: trailing spaces

(trailing-spaces)


65-72: Build Step Indentation in Build_Library Job
The comment and steps for building the library (lines 65–72) show an indentation issue (line 67 is reported as “expected 4 but found 2”). Please adjust the indentation within the steps block so that they are consistently indented relative to their parent job step.

🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 67-67: wrong indentation: expected 4 but found 2

(indentation)


74-86: Cleanup Trailing Spaces in Commented-Out Sections
Several commented-out steps for packaging additional libraries (lines 74, 78, 82, and 86) contain trailing spaces. Although these lines are commented, cleaning them up improves readability and consistency.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 74-74: trailing spaces

(trailing-spaces)


[error] 78-78: trailing spaces

(trailing-spaces)


[error] 82-82: trailing spaces

(trailing-spaces)


[error] 86-86: trailing spaces

(trailing-spaces)


145-170: Report_Build_Failure Job: Formatting Issues
Within the Report_Build_Failure job block (lines 145–170), YAMLlint has flagged multiple formatting issues:

  • Trailing spaces on lines 146, 160, and 165.
  • Indentation issues on lines 148 (expected 4 spaces but found 2) and 161.

Please fix these formatting issues to ensure the YAML passes linting and maintains a consistent style.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 146-146: trailing spaces

(trailing-spaces)


[warning] 148-148: wrong indentation: expected 4 but found 2

(indentation)


[error] 160-160: trailing spaces

(trailing-spaces)


[warning] 161-161: wrong indentation: expected 4 but found 2

(indentation)


[error] 165-165: trailing spaces

(trailing-spaces)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81298b0 and 0391ee1.

⛔ Files ignored due to path filters (45)
  • .editorconfig is excluded by none and included by none
  • README.md is excluded by !**/*.md and included by none
  • Stub-generation.md is excluded by !**/*.md and included by none
  • nanoFramework.Device.Can.Core.nuspec is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanController.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanControllerEventListener.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanControllerManager.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanEvent.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanMessage.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanMessageEvent.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanMessageFrameType.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanMessageIdType.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanMessageReceivedEventArgs.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/CanSettings.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/Properties/AssemblyInfo.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Core/key.snk is excluded by none and included by none
  • nanoFramework.Device.Can.Core/nanoFramework.Device.Can.Core.nfproj is excluded by none and included by none
  • nanoFramework.Device.Can.Core/packages.config is excluded by none and included by none
  • nanoFramework.Device.Can.Esp32.nuspec is excluded by none and included by none
  • nanoFramework.Device.Can.Esp32/Properties/AssemblyInfo.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Esp32/key.snk is excluded by none and included by none
  • nanoFramework.Device.Can.Esp32/nanoFramework.Device.Can.Esp32.nfproj is excluded by none and included by none
  • nanoFramework.Device.Can.Esp32/packages.config is excluded by none and included by none
  • nanoFramework.Device.Can.Mcp2515.nuspec is excluded by none and included by none
  • nanoFramework.Device.Can.Mcp2515/Properties/AssemblyInfo.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Mcp2515/key.snk is excluded by none and included by none
  • nanoFramework.Device.Can.Mcp2515/nanoFramework.Device.Can.Mcp2515.nfproj is excluded by none and included by none
  • nanoFramework.Device.Can.Mcp2515/packages.config is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32.nuspec is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanController.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanControllerEventListener.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanControllerManager.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanEvent.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanMessage.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanMessageEvent.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanMessageFrameType.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanMessageIdType.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanMessageReceivedEventArgs.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/CanSettings.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/Properties/AssemblyInfo.cs is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/key.snk is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/nanoFramework.Device.Can.Stm32.nfproj is excluded by none and included by none
  • nanoFramework.Device.Can.Stm32/packages.config is excluded by none and included by none
  • nanoFramework.Device.Can.sln is excluded by none and included by none
  • spelling_exclusion.dic is excluded by none and included by none
📒 Files selected for processing (7)
  • .github/.changelog-config.json (1 hunks)
  • .github/workflows/pr-checks.yml (1 hunks)
  • .github/workflows/update-dependencies.yml (2 hunks)
  • azure-pipelines.yml (2 hunks)
  • nanoFramework.Device.Can.Esp32/packages.lock.json (1 hunks)
  • nanoFramework.Device.Can.Mcp2515/packages.lock.json (1 hunks)
  • nanoFramework.Device.Can.Stm32/packages.lock.json (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • .github/workflows/update-dependencies.yml
  • .github/.changelog-config.json
  • nanoFramework.Device.Can.Stm32/packages.lock.json
  • nanoFramework.Device.Can.Esp32/packages.lock.json
  • nanoFramework.Device.Can.Mcp2515/packages.lock.json
🧰 Additional context used
🪛 YAMLlint (1.35.1)
azure-pipelines.yml

[error] 21-21: trailing spaces

(trailing-spaces)


[warning] 43-43: wrong indentation: expected 2 but found 0

(indentation)


[error] 58-58: trailing spaces

(trailing-spaces)


[warning] 67-67: wrong indentation: expected 4 but found 2

(indentation)


[error] 74-74: trailing spaces

(trailing-spaces)


[error] 78-78: trailing spaces

(trailing-spaces)


[error] 82-82: trailing spaces

(trailing-spaces)


[error] 86-86: trailing spaces

(trailing-spaces)


[error] 139-139: trailing spaces

(trailing-spaces)


[warning] 140-140: wrong indentation: expected 4 but found 2

(indentation)


[error] 146-146: trailing spaces

(trailing-spaces)


[warning] 148-148: wrong indentation: expected 4 but found 2

(indentation)


[error] 160-160: trailing spaces

(trailing-spaces)


[warning] 161-161: wrong indentation: expected 4 but found 2

(indentation)


[error] 165-165: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: nanoFramework.Device.Can (Build_Library)
  • GitHub Check: nanoFramework / NuGets using latest version
  • GitHub Check: nanoFramework.Device.Can (Report_Build_Failure)
  • GitHub Check: nanoFramework.Device.Can (Build_Library)
🔇 Additional comments (3)
.github/workflows/pr-checks.yml (2)

13-14: Consistency Update: Added Solution Parameter

The addition of the solution: 'nanoFramework.Device.Can.sln' parameter in the check_package_lock job aligns it with the existing configuration for the check_nuget_latest job. This change ensures both jobs reference the same solution file, which is essential for consistency as the repository transitions to a multi-package setup. Please verify that the solution filename matches the actual file in the repository.


15-20: Review Check: Matching Solution Reference in Both Jobs

The check_nuget_latest job already specifies the same solution file, which confirms cohesive usage across the workflow. Maintaining the consistency of the solution reference helps avoid potential misconfigurations in the build pipeline.

azure-pipelines.yml (1)

118-130: Update_Dependents Job: Condition Verification
The conditions for the Update_Dependents job (lines 118–130) are logically grouped. Please ensure that the variables used (such as StartReleaseCandidate and UPDATE_DEPENDENTS) are set appropriately elsewhere in the pipeline.

@frobijn
Copy link
Author

frobijn commented Feb 18, 2025

@josesimoes There is a bug in VersionCop that causes the build to fail.

Bug fix available in other PR.

@josesimoes
Copy link
Member

@frobijn noticed that. Just fixed it.

@Ellerbach
Copy link
Member

Why not using a shared project for common code? That would make things easier to maintain. And it's possible to have code conditions as well. All the M5Stack repo is built like this. This avoid duplication of code.

@frobijn
Copy link
Author

frobijn commented Feb 18, 2025

@Ellerbach There is a lot of duplicated code because I have not yet made the split between Core and Stm32 code. I'm going to do that in a subsequent PR. The purpose of this PR is: update the repository to produce three NuGet packages that depend on a fourth, check that the pipeline will run properly, and make sure the core team is happy about the new repository structure.

I've copied the current nanoFramework.Device.Can code to both Core and Stm32 projects. I thought it would make it easier to review the next PR with code split. It is then more obvious in which library the current code ends up, and also what code has to be changed to make the split work.

BTW personally I try to avoid shared projects, especially since I've read this answer by one of the Roslyn developers. Although shared code is understood when consumed by regular projects, Roslyn and thus Visual Studio get really confused when there is a problem with the regular projects that makes the shared code incomprehensible. If one of the regular projects is fine but another not, Visual Studio doesn't seem to understand that and some IDE features do not work properly (e.g. formatting/cleanup on save, F12). You can still share code by linking code from one project to another - that works very well, as the linked code is considered to be part of the regular project and all IDE features know what to do. Although the linked code file looks the same in the IDE as a file from a shared project, Roslyn/Visual Studio has a better understanding of what it is and the IDE works better. The difference may go away in future versions of Visual Studio, but for now I find shared projects much harder to work with.

@frobijn
Copy link
Author

frobijn commented Feb 18, 2025

So I guess the question is: is this the correct way the repository should be organized?

And: if I prepare the next PR with code changes, should I send that as a separate PR or include these changes as well? How to proceed from here?

@Ellerbach
Copy link
Member

I would prefer to directly have things clean. But ok to have subsequent PR.
And shared projects are the way to go with nano. Indeed, a shared projects totally out of any other project is just bunch of files. It takes all its interest, as explained, when liked to a project. In that case, multiple projects. And it's also the way to best share amongst various framework. I have .NET and .NET nanoFramework using shared project, it's just working perfectly.
You'll see, shared projects really works well! They "just" have to be used by a real project ;-)

@frobijn
Copy link
Author

frobijn commented Feb 18, 2025

It's not my experience that shared projects work well. Mileage may vary...

If the setup is now OK, then I'll start on the code changes.

@josesimoes
Copy link
Member

This is a WIP, duplicate code reported by sonarcloud will be addressed in future PRs.

@josesimoes josesimoes changed the base branch from main to can_vnext February 18, 2025 18:47
@josesimoes josesimoes enabled auto-merge (squash) February 18, 2025 18:50
@josesimoes josesimoes disabled auto-merge February 18, 2025 18:50
@josesimoes josesimoes merged commit a66cdf4 into nanoframework:can_vnext Feb 18, 2025
6 of 9 checks passed
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
60.5% Duplication on New Code (required ≤ 5%)

See analysis details on SonarQube Cloud

@frobijn frobijn deleted the new_pipeline branch February 20, 2025 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants