Commit 02b0967d authored by shRabbit's avatar shRabbit
Browse files

Complete .NET build CI/CD component

- Add templates/dotnet-build.yml with restore/build/test/publish jobs built on the official .NET SDK image
- Replace placeholder my-component.yml
- Update .gitlab-ci.yml to include and validate the component
- Rewrite README with usage, inputs and release instructions
parent 384cbe60
Loading
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
# This pipeline builds the component repository itself and keeps the
# `dotnet-build` component published at the referencing commit/tag.

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
@@ -5,23 +8,27 @@ workflow:
      when: never
    - when: always

include:
  # include the component located in the current project from the current SHA
  - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/my-component@$CI_COMMIT_SHA
    inputs:
      job_name: "component job of my-component"
      stage: build

stages:
  - build
  - test
  - release

ensure-job-added:
include:
  # Include the dotnet-build component located in this repository at the
  # current SHA so the component is validated on every push.
  - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/dotnet-build@$CI_COMMIT_SHA
    inputs:
      # The repository is just a component skeleton, so there is no real
      # solution to build. Override these when consuming the component.
      solution_path: "**/*.sln"
      tests_enabled: true
      publish_enabled: true

# Validate that the `dotnet-build` job was injected by the component.
ensure-component-added:
  stage: test
  image: badouralix/curl-jq
  rules:
    # project must be public for `curl` to access the API; using `CI_JOB_TOKEN` is insufficient!
    - if: $CI_PROJECT_VISIBILITY != "public"
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
@@ -31,7 +38,7 @@ ensure-job-added:
  script: |
    url="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs"
    curl --fail --show-error --silent "$url" |
    jq --exit-status 'map(select(.name | contains("component job of my-component"))) | length >= 1'
    jq --exit-status 'map(select(.name | contains("dotnet-build"))) | length >= 1'

create-release:
  stage: release
@@ -41,4 +48,4 @@ create-release:
  script: echo "Creating release $CI_COMMIT_TAG"
  release:
    tag_name: $CI_COMMIT_TAG
    description: "Release $CI_COMMIT_TAG of components repository $CI_PROJECT_PATH"
    description: "Release $CI_COMMIT_TAG of the dotnet-build component ($CI_PROJECT_PATH)"
 No newline at end of file
+51 −33
Original line number Diff line number Diff line
# Gitlab component template
# GitLab .NET Build Component

<!--
Update this readme with your component details. Replace content in `< >` with your project information.
For more information:
![Latest Release](https://shrabbit.com:4000/gitlab/pipelines/dotnet-build/-/badges/release.svg)

- How to create a CI/CD component: https://docs.gitlab.com/ee/ci/components/#write-a-component
- How to write a clear README.md file: https://docs.gitlab.com/ee/ci/components/#write-a-clear-readmemd
- CI/CD Component security best practices: https://docs.gitlab.com/ee/ci/components/#cicd-component-security-best-practices
-->
用于构建 .NET Core / .NET 项目的 GitLab CI/CD [组件 (component)](https://docs.gitlab.com/ee/ci/components/)

<!-- Uncomment and update the following link to display a release badge: https://docs.gitlab.com/ee/user/project/badges.html#latest-release-badges -->
<!-- [![Latest Release](https://gitlab.com/<your project path>/-/badges/release.svg)](https://gitlab.com/<your project path>/-/releases) -->
组件提供四个任务:`dotnet-restore``dotnet-build``dotnet-test``dotnet-publish`,全部运行在官方 `mcr.microsoft.com/dotnet/sdk` 镜像中。

## Components
## 快速开始

### `<Component-name>`

Use this component to `<component-description>`.

To add this component to your CI/CD pipeline, add the following include entry to your
project's CI/CD configuration:
在你的项目 `.gitlab-ci.yml` 中添加如下 include:

```yaml
include:
  - component: https://gitlab.com/<your project path>/<name of your template>@<tag>
  - component: $CI_SERVER_FQDN/pipelines/dotnet-build/dotnet-build@<version>
    inputs:
      dotnet_version: "8.0"
      solution_path: "**/*.sln"
      tests_enabled: true
      publish_enabled: true
```

Where `<tag>` is the release tag you want to use ([releases list](https://gitlab.com/<your-project-path>/-/releases)).
其中 `<version>` 是你要使用的发布标签(见 [Releases](https://shrabbit.com:4000/gitlab/pipelines/dotnet-build/-/releases))。

## Inputs

The template contains some optional [inputs](https://docs.gitlab.com/ee/ci/yaml/inputs.html):
| Input              | 默认值     | 说明                                        |
|--------------------|-----------|---------------------------------------------|
| `dotnet_version`   | `8.0`     | .NET SDK 版本,用作镜像标签                 |
| `configuration`    | `Release` | MsBuild 构建配置                            |
| `solution_path`    | (空)      | 要构建的 `.sln`/`.csproj` 路径,空则构建默认项目 |
| `tests_enabled`    | `false`   | 是否启用 `dotnet-test` 任务                 |
| `publish_enabled`  | `false`   | 是否启用 `dotnet-publish` 任务              |
| `publish_output`   | `publish` | 发布任务输出目录                            |
| `stage`            | `build`   | 所有任务所属的流水线 stage                  |

## 任务说明

- **dotnet-restore**:还原 NuGet 依赖。`solution_path` 为空时自动跳过。
- **dotnet-build**:编译解决方案,并将 `bin/<configuration>` 输出作为工件上传。
- **dotnet-test**`tests_enabled: true` 时运行测试,产出 JUnit 报告。
- **dotnet-publish**`publish_enabled: true` 时生成可部署输出。

若你的项目不需要包含此组件仓库自身的流水线,可忽略仓库内的 `.gitlab-ci.yml`,它仅用于在推送时验证组件可用。

<!-- Add or update rows if you change the inputs in the template -->
## 组件结构

| Input      | Default value    | Description |
|------------|------------------|-------------|
| `job_name` | `job-template`   | The job name. |
| `image`    | `busybox:latest` | The container image to use to run the job. |
| `stage`    | `test`           | The stage name for the job. |
```
.
├── templates/
│   └── dotnet-build.yml   # 组件本体
├── .gitlab-ci.yml          # 仓库自身流水线(验证组件)
├── LICENCE                 # 许可证
└── README.md
```

## 发布组件

## Documentation
打一个版本标签即可将当前组件作为可复用的版本发布:

```bash
git tag <version>
git push origin <version>
```

This project includes a MVC structure to help you get started with [Gitlab CI/CD components](https://docs.gitlab.com/ee/ci/components/).
The template provides the basic file structure to create your own single component.
This project should be public, or one of the jobs in the project's pipeline won't work.
打标签会触发 `create-release` 任务并生成 Release。

## Licence
## 许可证

The licence can be changed. By default this project has the [MIT Licence](./LICENCE).
<!-- You should update the year and name in the license file. -->
[MIT](./LICENCE).
 No newline at end of file
+126 −0
Original line number Diff line number Diff line
# GitLab CI/CD component to restore, build, test and publish .NET Core / .NET projects.
#
# Reference: https://docs.gitlab.com/ee/ci/components/
#
# Quick usage in a consumer pipeline:
#
#   include:
#     - component: $CI_SERVER_FQDN/pipelines/dotnet-build/dotnet-build@<tag>
#       inputs:
#         dotnet_version: "8.0"
#         solution_path: "**/*.sln"
#         tests_enabled: true
#
# All jobs run in the official .NET SDK image `mcr.microsoft.com/dotnet/sdk`.

spec:
  inputs:
    # .NET SDK version (major.minor) used as the image tag.
    dotnet_version:
      default: "8.0"
    # The MsBuild configuration to restore/build/publish with.
    configuration:
      default: Release
    # Glob path to the .sln / .csproj to build. Leave empty to build the default
    # project found in the repository root.
    solution_path:
      default: ""
    # Set to "true" to enable the test job. The test command targets the restored
    # solution unless `test_project_path` is provided.
    tests_enabled:
      default: false
    # Set to "true" to enable the publish job.
    publish_enabled:
      default: false
    # Output folder for the publish job.
    publish_output:
      default: publish
    # Pipeline stage all the generated jobs run in.
    stage:
      default: build

---
variables:
  # Resolve inputs to plain variables so consumers can reference/override them.
  DOTNET_VERSION: "$[[ inputs.dotnet_version ]]"
  BUILD_CONFIGURATION: "$[[ inputs.configuration ]]"
  BUILD_SOLUTION: "$[[ inputs.solution_path ]]"
  RUN_TESTS: "$[[ inputs.tests_enabled ]]"
  ENABLE_PUBLISH: "$[[ inputs.publish_enabled ]]"
  PUBLISH_OUTPUT: "$[[ inputs.publish_output ]]"

# Restore NuGet packages. Skipped automatically if `solution_path` is empty.
dotnet-restore:
  image: "mcr.microsoft.com/dotnet/sdk:$DOTNET_VERSION"
  stage: $[[ inputs.stage ]]
  variables:
    NUGET_RESTORE_ARGS: "$[[ inputs.solution_path ]]"
  script:
    - if [ -z "$NUGET_RESTORE_ARGS" ]; then echo "No solution/project specified, skipping restore." && exit 0; fi
    - dotnet restore "$NUGET_RESTORE_ARGS" --configuration "$BUILD_CONFIGURATION"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - when: always

# Compile the solution/project and keep the build output as an artifact.
dotnet-build:
  image: "mcr.microsoft.com/dotnet/sdk:$DOTNET_VERSION"
  stage: $[[ inputs.stage ]]
  variables:
    DOTNET_BUILD_ARGS: "$[[ inputs.solution_path ]]"
  script:
    - dotnet build "$DOTNET_BUILD_ARGS" --configuration "$BUILD_CONFIGURATION" --no-restore
  artifacts:
    paths:
      - "**/bin/$BUILD_CONFIGURATION/**"
    exclude:
      - "**/obj/**"
    expire_in: 7 days
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - when: always

# Run the full test suite (enabled via the `tests_enabled` input).
dotnet-test:
  image: "mcr.microsoft.com/dotnet/sdk:$DOTNET_VERSION"
  stage: $[[ inputs.stage ]]
  variables:
    DOTNET_TEST_ARGS: "$[[ inputs.solution_path ]]"
  script:
    - dotnet test "$DOTNET_TEST_ARGS" --configuration "$BUILD_CONFIGURATION" --no-restore --no-build
  artifacts:
    when: always
    reports:
      junit: "**/TestResults/TEST-*.xml"
    expire_in: 7 days
  rules:
    - if: '$RUN_TESTS != "true"'
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - when: always

# Produce a deployable output (enabled via the `publish_enabled` input).
dotnet-publish:
  image: "mcr.microsoft.com/dotnet/sdk:$DOTNET_VERSION"
  stage: $[[ inputs.stage ]]
  variables:
    DOTNET_PUBLISH_ARGS: "$[[ inputs.solution_path ]]"
  script:
    - dotnet publish "$DOTNET_PUBLISH_ARGS" --configuration "$BUILD_CONFIGURATION" --no-restore --no-build --output "$PUBLISH_OUTPUT"
  artifacts:
    paths:
      - "$PUBLISH_OUTPUT/**"
    expire_in: 30 days
  rules:
    - if: '$ENABLE_PUBLISH != "true"'
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - when: always
 No newline at end of file

templates/my-component.yml

deleted100644 → 0
+0 −23
Original line number Diff line number Diff line
spec:
  inputs:
    # These are examples of inputs.
    job_name:
      default: job-template
    image:
      default: busybox:latest
    stage:
      default: test

---
# This is an example of a job using inputs
# use variables with this syntax : $[[ inputs.xxx ]]
$[[ inputs.job_name ]]:
  image: $[[ inputs.image ]]
  stage: $[[ inputs.stage ]]
  script:
    - echo "Starting job $[[ inputs.job_name ]]"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - when: always