Skip to content

Latest commit

 

History

History
265 lines (201 loc) · 15.6 KB

File metadata and controls

265 lines (201 loc) · 15.6 KB

Contributing

Thank you for considering a contribution to NINA! There are many areas where you can contribute, ranging from improving the documentation, writing tutorials, submitting bugs or even writing code for new features inside NINA itself. Before contributing code or documentation, please start a discussion via GitHub Issues or Discord. This helps ensure alignment and avoids duplicate work.

Ways to Contribute

Whether you're a developer, power user, translator, or just enthusiastic about astronomy, there are many ways to contribute:

  • Fixing bugs and implementing new features
  • Writing or improving documentation
  • Creating tutorials or user guides
  • Improving translations
  • Suggesting and discussing new features
  • Writing or maintaining plugins
  • Participating in community discussions

Bug Reporting

If you encounter a bug with N.I.N.A. you can report this via the issue tracker

Checklist

  1. Ensure that the problem still persists on the latest version
  2. If the problem still persists, check the issue tracker if there is already an issue open for it
  • An issue for your problem exists
    • Check that this issue describes the exact same issue that you are having
    • Add all information that you have to the issue. Just adding "me too" won't help us much to resolve it.
    • The more info is available for an issue, the better and faster we can track down the root cause and fix it!
  • If no issue is already existing create a new one

What to include

For reporting bugs please use the following guideline to describe the problem:

[ ] Is the issue reproducible?  
[ ] Are you running the latest version?  
[ ] Are all prerequisites that are mentioned inside the manual met?  

# Description #

<Put a short description about the issue here>

# Steps to Reproduce #
* <Step 1>
* <Step 2>
* <and so on>

## Expected behaviour ##
<describe what should happen>
## Actual behaviour ##
<describe what actually happened>

Also attach your log file of that session (if applicable), which can be found inside %localappdata%\NINA\Logs

Contributing documentation

Contributing code

Quick start

  1. Fork the repository
  2. Sync LFS files into the fork
git clone -n -b develop https://<YourUserName>@github.com/<YourUserName>/<YourForkName>.git
# NOTE: the -n flag for "don't checkout the branch"
# Ignore any LFS smudge errors for now. They are not yet synced and will get synced in a later step
cd <YourForkName>
git remote add upstream https://github.com/isbeorn/nina.git
git lfs fetch upstream --all
git lfs push origin --all
git checkout <desired branch>
git submodule update --init --recursive
  1. Add your changes
  2. Check that unit tests are passing
  3. Ensure no unintended or unnecessary files are committed.
  4. Add a short description about your changes to the correct section inside "RELEASE_NOTES.md"
  5. Push the change to your forked repository using a good commit message
  6. Submit a pull request
  7. During pull requests, expect discussions and constructive feedback. Required changes that might be requested during this phase have to be implemented. Once this is done, the pull request can be merged.

Repository navigation

  • Before making non-trivial changes, read the repository-level AGENTS.md
  • Read the ARCHITECTURE.md file in the project you are changing before making structural changes there
  • AGENTS.md links the project architecture documents and explains solution-wide boundaries, startup/composition, localization, plugin/sequencer surfaces, and other cross-cutting rules
  • If a change depends on durable project knowledge that is only in an issue, Discord thread, or review comment, add it to the appropriate checked-in doc, test, or automation.

Coding rules

  • Always be backwards compatible when having some major rework of a module (e.g. settings change)
  • Follow the checked-in .editorconfig for C# style and formatting
  • Prefer modern C# syntax that is supported by the target project instead of preserving older patterns unnecessarily
  • For new or refactored MVVM code, prefer the referenced CommunityToolkit.Mvvm APIs and attributes over older local relay-command wrappers
  • Follow clean code guidelines. There are many resources about this topic available online.
  • Add or update focused unit tests for behavior changes. If a behavior change cannot reasonably be automated, explain the manual verification path in the pull request.
  • Avoid introducing new build warnings. If a warning must remain, make the reason clear in the pull request so it can be tracked deliberately.

AI / Tool-Assisted Contributions

AI tools and other content-generating tools may be used to assist with contributions, but the human contributor remains fully responsible for everything submitted.

Trivial tool use does not require disclosure. This includes examples such as formatting, spelling or grammar cleanup, identifier completion, simple boilerplate completion, and purely mechanical renames.

If a meaningful amount of code, tests, changelog text, or documentation was generated or materially shaped by an AI tool or another non-trivial generation tool, disclose the tool or model used in the pull request description.

Do not submit generated content that you do not fully understand or cannot defend during review.

The submitting human is responsible for correctness, provenance, licensing compliance, and repository policy compliance.

Maintainers may request additional explanation or validation for AI-assisted submissions, and may reject submissions that lack sufficient transparency, understanding, or verification.

Branching model

This project is utilizing a standard git flow where it has the following branches

  • master: all officially released code
  • hotfix/: used to fix critical issues inside master
  • release/: when preparing a release with new features a temporary release branch is created for that new release
  • bugfix/: issues that are found during a release will be fixed here
  • develop: a general develop branch that will contain unreleased new features
  • feature/: new features that will be developed and merged to the develop branch

A more in-depth guide about this model can be found here

Versioning in N.I.N.A.

N.I.N.A. utilizes the versioning scheme MAJOR.MINOR.PATCH.CHANNEL|BUILDNRXXX
There is currently no automation used and versions are maintained manually.

MAJOR version increases for big changes, like changing technologies etc.

MINOR version will increase for every new released version

PATCH version is reserved to apply Hotfixes to a released versions

CHANNEL|BUILDNR will not be displayed for Released versions, as these are only used to identify Release, RC, Beta and Develop versions

CHANNEL consists of the following values:

  • 1: Nightly
  • 2: Beta
  • 3: Release Candidate
  • 9: Release

BUILDNR should be incremented each nightly build (only in develop,beta and rc versions) by using 3 digits.

Examples: Release: 1.8.0.9001 (Displayed as "1.8")
Release: 1.8.1.9001 (Displayed as "1.8 HF1")
Release Candidate: 1.8.0.3001 (Displayed as "1.8 RC1")
Beta: 1.8.0.2004 (Displayed as "1.8 BETA4")
Develop: 1.8.0.1022 (Displayed as "1.8 NIGHTLY #022")

Database enhancements

N.I.N.A. uses an SQLite database to store various data. The database is located inside %LOCALAPPDATA%\NINA\NINA.sqlite. This database will be automatically created by the EntityFramework based on the files inside \NINA\Database\Initial and \NINA\Database\Migration

  • Files inside "Initial" folder will be called when the database needs to be created from scratch.
    • Do not alter these files! Changes here won't get applied for an existing database (e.g. from a previous version)
    • In case additions have to be made to the database, add a new migration file as described below
  • Files inside migration will be called depending on the current version that is returned via "PRAGMA user_version" of the existing database
    • The migration is kept simple and follows a naming convention. The migration .sql file matches the version it should migrate to. (Files are named like "1.sql", "2.sql" etc.)
    • This requires that the same user_version is set as the file name specifies inside the file (e.g. "1.sql" must contain a "PRAGMA user_version = 1;" statement)
    • Only those files where the version is greater than the current database user_version will be executed
  • During migration the foreign key constraints are deactivated, for easier data manipulation. Be cautious to not corrupt data that way!
  • After a migration a VACUUM will be performed

Setting up the developer environment

  • Install Visual Studio Community 2026
  • Install .NET 10.0 SDK
  • Install ASCOM
  • Recommended Visual Studio Extensions:
  • Static external dependencies are hosted in a separate git repository and pulled as a submodule, so they need to be checked out separately
    • git submodule update --init --recursive on the first checkout

    • git submodule update --recursive to update the submodule to the latest version

    • Having submodules for these files has the advantage that the fork doesn't have to host the files again and run into available LFS space limits

    • To get Canon and Nikon DLLs you have to register as a developer for canon and nikon separately on their websites

    • Due to not being publicly available, they must not be put into a public repository

  • Other external dependencies are automatically installed via nuget (except for some camera vendor DLLs)
  • (Optional) The NINA project has a post install action to build the offline documentation via mkdocs from the docs submodule. Follow the steps to be able to build the documentation in the contributing guide of the docs repository
  • (Optional) To be able to build the setup projects you need to install WiX and the Visual Studio plugin

Automated Unit Tests (AUT)

  • The project is using the NUnit unit-testing framework to write and run AUTs
  • Additionally to write easy to read assertions Fluent Assertions are used
    • These might seem verbose at first, but they really help reading and understanding the assertions
  • For detailed information about how to use these frameworks please go to their respective homepages

Running AUTs from the command line

The repository CI uses the .NET CLI on Windows. The same basic flow can be used locally:

dotnet restore NINA.sln
dotnet build NINA/NINA.csproj --configuration Debug --no-restore
dotnet build NINA.Test/NINA.Test.csproj --configuration Debug --no-restore
dotnet test NINA.Test/NINA.Test.csproj --configuration Debug --no-build -p:PlatformTarget=x64

Running AUTs in Visual Studio

  • First double check that your processor architecture for AUTs is set to x64
    • Test -> Test Settings -> Processor Architecture for AnyCPU Projects -> x64
    • You also might need to uncheck and re-check "Keep Test Execution Engine Running" for this setting change to become active
  • Prior to running the tests, the project configuration should be set to [Debug][x64]
  • Activate the test explorer
    • Test -> Windows -> Test Explorer
  • Inside the test explorer you will see all detected AUTs (after building the project)
  • To run all AUTs simply click on "Run All"
  • You can also run and/or debug single AUTs by right clicking inside the respective method and selecting "Run Test" or "Debug Test"

Localization

  • All strings that are displayed inside the User Interface should be localized using the Locale Manager
    • In Code Behind: NINA.Core.Locale.Loc.Instance["[Label key]"]
    • In XAML:
      • Import namespace: xmlns:ns="clr-namespace:NINA.Core.Locale;assembly=NINA.Core"
      • Use via binding like Text="{ns:Loc [Label key]}"
  • To introduce a new label, add the new key and value only to NINA.Core/Locale/Locale.resx. The other localized files will be managed by an external integration automatically.
  • All translations are managed by an external page at Crowdin and automatically integrated into the repository
    • For more information on how to contribute to the localization refer to our documentation in the contributing section

Pull Requests

  • Before making large changes, that will change existing patterns or disrupt ongoing features, please first discuss this via an issue or in discord, before starting to work on the changes! This way we can make sure, that it is the proper time for this change.

  • Make sure that only relevant changes are inside the pull request

  • Validate that all unit tests are still passing

  • Test your changes thoroughly and give a short overview on how you tested your changes in the pull request's description

  • Include any notable skipped tests, warnings, environment constraints, or manual verification limits in the pull request description.

  • Add yourself to the AUTHORS file, so you will be given proper credit!

  • Create one pull request per feature/fix

  • Create your pull requests for new features only against the develop branch

    • Only critical Hotfixes may be created against master branch and require a new PATCH version as described in [Versioning in N.I.N.A.]
  • Fill out the live pull request template in .github/pull_request_template.md

NINA.SetupBundle Prerequisites

  • To provide release notes for the setup bundle and generate the release notes html file, there is a build event using "pandoc" that creates an these files out of RELEASE_NOTES.md
  • Pandoc is expected to be inside the folder "%LOCALAPPDATA%\Pandoc\pandoc.exe"
  • Setup can be downloaded at https://pandoc.org/installing.html

IoC Container

  • We use Microsoft.Extensions.DependencyInjection to inject dependencies into classes
  • Everything that is created as a first-level composition object and all of their dependencies are automatically created on runtime and injected into the appropriate classes
  • Should you require a global singleton add the interface of that to your constructor, it will be automatically injected if your class is instantiated by DI
  • If you create a VM that is used by the UI or refactor things out of VMs into generalized structures bind them in IoCBindings.cs, so they can be easily injected into the VMs you removed them from
    • if you create a VM that has an anchorable view, inject it into DockManagerVM so it's automatically instantiated
    • if the VM you create is for Equipment, do the same but in EquipmentVM
    • If you are creating a first-level composition object that is used in MainWindow.xaml/MainWindowVM.cs create it in CompositionRoot.cs and bind it as a Singleton in IoCBindings.cs