Skip to content

Latest commit

 

History

History
246 lines (153 loc) · 14 KB

CONTRIBUTING.md

File metadata and controls

246 lines (153 loc) · 14 KB

Contribution Guidelines

After following the instructions to set up your instance, please read below for guidelines on contributions to RIA Hub.

Guidelines for Backend Development

Backend Background

Gitea uses Golang as the backend programming language. It uses many third-party packages and also writes some itself. For example, Gitea uses Chi as a basic web framework. Xorm is an ORM framework that is used to interact with the database. So it's very important to manage these packages. Please take the below guidelines before you start to write backend code.

Package Design Guideline

Packages List

To maintain understandable code and avoid circular dependencies, it is important to have a good code structure. The Gitea backend is divided into the following parts:

  • build: Scripts to help build Gitea.
  • cmd: All Gitea actual subcommands, including web, doctor, serv, hooks, admin, etc. web will start the web service. serv and hooks will be invoked by Git or OpenSSH. Other subcommands could help to maintain Gitea.
  • tests: Common test utility functions.
    • tests/integration: Integration tests, to test back-end regressions.
    • tests/e2e: End-to-end tests, to test front-end and back-end compatibility and visual regressions.
  • models: Contains the data structures used by xorm to construct database tables. It also contains functions to query and update the database. Dependencies to other Gitea code should be avoided, with exceptions like logging.
    • models/db: Basic database operations. All other models/xxx packages should depend on this package. The GetEngine function should only be invoked from models/.
    • models/fixtures: Sample data used in unit tests and integration tests. One yml file means one table, which will be loaded into the database when tests begin.
    • models/migrations: Stores database migrations between versions. PRs that change a database structure MUST also have a migration step.
  • modules: Different modules to handle specific functionality in Gitea. (Work in Progress: Some should be moved to services, particularly those that depend on models.)
    • modules/setting: Stores all system configurations read from ini files and is referenced everywhere. Should be used as function parameters when possible.
    • modules/git: Package to interact with Git command line or Gogit package.
  • public: Compiled frontend files (JavaScript, images, CSS, etc.).
  • routers: Handles server requests. As it uses other Gitea packages to serve requests, other packages (models, modules, or services) must not depend on routers.
    • routers/api: Contains routers for /api/v1, aimed to handle RESTful API requests.
    • routers/install: Responds only when the system is in INSTALL mode (INSTALL_LOCK=false).
    • routers/private: Invoked only by internal subcommands, especially serv and hooks.
    • routers/web: Handles HTTP requests from web browsers or Git SMART HTTP protocols.
  • services: Support functions for common routing operations or command executions. Uses models and modules to handle requests.
  • templates: Golang templates for generating HTML output.

Package Dependencies

Since Golang doesn't support import cycles, we have to decide package dependencies carefully. There are some levels between packages. Below is the ideal package dependency direction:

cmd -> routers -> services -> models -> modules

From left to right, packages on the left can depend on packages on the right, but packages on the right MUST not depend on those on the left. Subpackages on the same level may depend according to this level's rules.

Package Name

For top-level packages, use a plural as the package name, i.e., services, models. For subpackages, use the singular, i.e., services/user, models/repository.

Import Alias

Since some packages use the same package name, you might encounter packages like modules/user, models/user, and services/user. When these packages are imported in one Go file, it's difficult to know which package is being used and whether it's a variable or import name. Therefore, it is recommended to use import aliases. To differentiate from package variables (which are commonly in camelCase), use snake_case for import aliases, e.g., import user_service "code.gitea.io/gitea/services/user".

Guidelines for Frontend Development

Frontend Background

Gitea uses Fomantic-UI (based on jQuery) and Vue3 for its frontend.

The HTML pages are rendered by Go HTML Template.

The source files can be found in the following directories:

  • CSS styles: web_src/css/
  • JavaScript files: web_src/js/
  • Vue components: web_src/js/components/
  • Go HTML templates: templates/

General Guidelines

We recommend the following style guides:

Gitea Specific Guidelines

  • Every feature (Fomantic-UI/jQuery module) should be put in separate files/directories.
  • HTML ids and classes should use kebab-case and contain 2-3 feature-related keywords.
  • HTML ids and classes used in JavaScript should be unique across the entire project and contain 2-3 feature-related keywords. Use the js- prefix for classes that are only used in JavaScript.
  • Avoid overwriting CSS styling for framework-provided classes. Use new class names with 2-3 feature-related keywords. Gitea's helper CSS classes in helpers.less could be useful.
  • The backend can pass complex data to the frontend by using ctx.PageData["myModuleData"] = map[]{}, but do not expose entire models to the frontend to avoid leaking sensitive data.
  • Simple and SEO-related pages should use Go HTML Template to generate static Fomantic-UI HTML output. More complex pages can use Vue3.
  • Clarify variable types. Prefer elem.disabled = true instead of elem.setAttribute('disabled', 'anything'). Prefer $el.prop('checked', var === 'yes') instead of $el.prop('checked', var).
  • Use semantic elements. Prefer <button class="ui button"> over <div class="ui button">.
  • Avoid unnecessary !important in CSS. Add comments to explain why it's necessary if it cannot be avoided.
  • Avoid mixing different events in one event listener. Use individual event listeners for each event.
  • Custom event names should use the ce- prefix.
  • Prefer using Tailwind CSS, which is available via the tw- prefix (e.g., tw-relative). Gitea's helper CSS classes use the gt- prefix (e.g., gt-word-break), and Gitea's private framework-level CSS classes use the g- prefix (e.g., g-modal-confirm).
  • Avoid inline scripts and styles as much as possible. It's recommended to put JS code into JS files and use CSS classes. If inline scripts/styles are unavoidable, explain the reason why.

Framework Usage

Mixing different frameworks is discouraged, as it makes code difficult to maintain. A JavaScript module should follow one major framework and adhere to that framework's best practices.

Recommended implementations:

  • Vue + Vanilla JS
  • Fomantic-UI (jQuery)
  • htmx (for partial page reloads in otherwise static components)
  • Vanilla JS

Discouraged implementations:

  • Vue + Fomantic-UI (jQuery)
  • jQuery + Vanilla JS
  • htmx with any other framework that requires heavy JS code or unnecessary features like htmx scripting (hx-on)

For consistent UI, Vue components can use Fomantic-UI CSS classes. Use htmx for simple interactions, as seen in this PR. Do not use htmx for more advanced reactivity; use another framework like Vue or Vanilla JS. While mixing frameworks is discouraged, it can work if necessary and if the code is well-designed and maintainable.

Fetching Data

To fetch data, use wrapper functions GET, POST, etc. from modules/fetch.js. They accept a data option for content, will automatically set the CSRF token, and return a Promise for a Response.

HTML Attributes and dataset

Avoid using dataset, as its camel-casing behavior makes attributes hard to grep. However, there are some exceptions:

For legacy code:

  • Refactor $.data() to $.attr().
  • Use $.data() in rare cases to bind non-string data to elements, but this is discouraged.

For new code:

  • Do not use node.dataset, use node.getAttribute instead.
  • Never bind user data to a DOM node. Use suitable design patterns to describe the relationship between node and data.

Show/Hide Elements

For Vue components, use v-if and v-show to show/hide elements. In Go template code, use .tw-hidden and showElem(), hideElem(), or toggleElem(). See more details in .tw-hidden's comments.

Styles and Attributes in Go HTML Template

It is recommended to use:

<div class="gt-name1 gt-name2 {{if .IsFoo}}gt-foo{{end}}" {{if .IsFoo}}data-foo{{end}}></div>
<div class="gt-name1 gt-name2{{if .IsFoo}} gt-foo{{end}}"{{if .IsFoo}} data-foo{{end}}></div>

to make the code more readable.

Vue3 and JSX

Gitea is using Vue3 now. We decided not to introduce JSX to keep the HTML and JavaScript code separated.

UI Examples

Gitea uses some custom UI elements and customizes others to better integrate them into the general UI approach. When running Gitea in development mode (RUN_MODE=dev), a page with standardized UI examples is available at http(s)://your-gitea-url:port/devtest.

Styleguide

You should always run make fmt before committing to conform to Gitea's styleguide.

Testing

Before submitting a pull request, run all tests to make sure your changes don't cause a regression elsewhere.

Here's how to run the test suite:

  • code lint
make lint lint everything (not needed if you only change the front- or backend)
make lint-frontend lint frontend files
make lint-backend lint backend files
  • run tests (we suggest running them on Linux)
Command Action
make test[\#SpecificTestName] run unit test(s)
make test-sqlite[\#SpecificTestName] run integration test(s) for SQLite More details
make test-e2e-sqlite[\#SpecificTestName] run end-to-end test(s) for SQLite More details

PRs

Always open PRs with any changes and do not merge directly into main.

General Guidelines for GitHub

  1. Write clear and meaningful commit messages.

  2. Use “atomic commits” -- atomic commits are small, focused commits that address a single, cohesive change. Rationale: Atomic commits provide a clear, granular, and efficient history, facilitating collaboration, bug identification, and integration with CI/CD pipelines.

  3. Ensure development is completed on dedicated feature branches -- never push changes directly to main. Rationale: Required to keep main stable.

  4. Always pull the latest changes prior to pushing changes. Rationale: Minimizes the risk of conflicts.

  5. Do not version user-specific settings and configurations (which may not be relevant or compatible across different developers or environments), temporary files, data files, or any files that can be generated from the source code. Use a .gitignore file to specify file patterns that should be ignored. Rationale: Keeps the repo clean and focused.

  6. Please avoid making changes to the commit history after the pull request is opened.

  7. Merge is best used when the target branch is supposed to be shared. Rebase is best used when the target branch is private.

Guidelines for Pull Requests (PRs)

Guidelines for Pull Requests

Pull requests (PRs) are a mechanism where proposed changes to a codebase are submitted for review and integration, facilitating collaborative development. When you are ready to integrate your changes into main, please submit a PR. Rationale: Code review allows other collaborators to provide feedback and catch potential issues.

You can notify other collaborators on the right side of your screen when making a PR and you can send them the link directly for review.

Before submitting a pull request, ensure that most or all of the following criteria are met:

  • Title is descriptive

  • Detailed description of the changes made in the PR

  • If there is a specific issue then it is referenced in the description (eg. "Closes," "Fixes," or "Resolves" issue X)

  • Feature branch is up-to-date with target branch by regular rebasing

  • Extensive testing was run before opening PR

  • No merge conflicts

Guidelines for Pull Request Comments

In the pull request comments, provide a detailed description of additions, removals, and fixes, including explanations for changes in the implementation; leverage markdown for well-structured comments with bullet points and consider adding images or GIFs, particularly for UI modifications (drag and drop images are supported). If any aspects of the issue were not addressed, leave a note at the bottom of the comments for ongoing reference.

In essence, the goal is (assuming PR has no conflicts with main) that someone who has been collaborating with you should easily be able to approve/add comments to the PR without having to go to the code or do any test runs. All of this information should be communicated with them in the PR notes.

Exemplar Pull Request

image

Building continuously

To run and continuously rebuild when source files change:

# for both frontend and backend
make watch

# or: watch frontend files (html/js/css) only
make watch-frontend

# or: watch backend files (go) only
make watch-backend