Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: CI/CD Pipeline

on: [push, pull_request, workflow_dispatch]

jobs:
ci:
name: Continuous Integration
runs-on: ubuntu-latest
outputs:
latest_version: ${{ steps.tag_generator.outputs.new_version }}
is_default_branch: ${{ steps.conditionals_handler.outputs.is_default_branch }}
env:
ARTIFACTS_FOLDER: ${{ github.workspace }}/Artifacts
GITHUB_RUN_NUMBER: ${{ github.run_number }}
steps:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x

- name: Data gatherer
id: data_gatherer
shell: pwsh
run: |
# Get default branch
$repo = 'microsoft/OpenAPI.NET'
$defaultBranch = Invoke-RestMethod -Method GET -Uri https://api.github.com/repos/$repo | Select-Object -ExpandProperty default_branch
Write-Output "::set-output name=default_branch::$(echo $defaultBranch)"

- name: Conditionals handler
id: conditionals_handler
shell: pwsh
run: |
$defaultBranch = "${{ steps.data_gatherer.outputs.default_branch }}"
$githubRef = "${{ github.ref }}"
$isDefaultBranch = 'false'
if ( $githubRef -like "*$defaultBranch*" ) {
$isDefaultBranch = 'true'
}
Write-Output "::set-output name=is_default_branch::$(echo $isDefaultBranch)"

- name: Checkout repository
id: checkout_repo
uses: actions/checkout@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0

- if: steps.conditionals_handler.outputs.is_default_branch == 'true'
name: Bump GH tag
id: tag_generator
uses: mathieudutour/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
default_bump: false
release_branches: ${{ steps.data_gatherer.outputs.default_branch }}

- name: Build projects
id: build_projects
shell: pwsh
run: |
$projectsArray = @(
'.\src\Microsoft.OpenApi\Microsoft.OpenApi.csproj',
'.\src\Microsoft.OpenApi.Readers\Microsoft.OpenApi.Readers.csproj',
'.\src\Microsoft.OpenApi.Tool\Microsoft.OpenApi.Tool.csproj'
)
$gitNewVersion = if ("${{ steps.tag_generator.outputs.new_version }}") {"${{ steps.tag_generator.outputs.new_version }}"} else {$null}
$projectCurrentVersion = ([xml](Get-Content .\src\Microsoft.OpenApi\Microsoft.OpenApi.csproj)).Project.PropertyGroup.Version
$projectNewVersion = $gitNewVersion ?? $projectCurrentVersion

$projectsArray | ForEach-Object {
dotnet build $PSItem `
-c Release # `
# -o $env:ARTIFACTS_FOLDER `
# /p:Version=$projectNewVersion
}

# Move NuGet packages to separate folder for pipeline convenience
# New-Item Artifacts/NuGet -ItemType Directory
# Get-ChildItem Artifacts/*.nupkg | Move-Item -Destination "Artifacts/NuGet"

- name: Run unit tests
id: run_unit_tests
shell: pwsh
run: |
$testProjectsArray = @(
'.\test\Microsoft.OpenApi.Tests\Microsoft.OpenApi.Tests.csproj',
'.\test\Microsoft.OpenApi.Readers.Tests\Microsoft.OpenApi.Readers.Tests.csproj',
'.\test\Microsoft.OpenApi.SmokeTests\Microsoft.OpenApi.SmokeTests.csproj'
)

$testProjectsArray | ForEach-Object {
dotnet test $PSItem `
-c Release
}

# - if: steps.tag_generator.outputs.new_version != ''
# name: Upload NuGet packages as artifacts
# id: ul_packages_artifact
# uses: actions/upload-artifact@v1
# with:
# name: NuGet packages
# path: Artifacts/NuGet/

cd:
if: needs.ci.outputs.is_default_branch == 'true' && needs.ci.outputs.latest_version != ''
name: Continuous Deployment
needs: ci
runs-on: ubuntu-latest
steps:
# - name: Download and extract NuGet packages
# id: dl_packages_artifact
# uses: actions/download-artifact@v2
# with:
# name: NuGet packages
# path: NuGet/

# - name: Push NuGet packages to NuGet.org
# id: push_nuget_packages
# continue-on-error: true
# shell: pwsh
# run: |
# Get-ChildItem NuGet/*.nupkg | ForEach-Object {
# nuget push $PSItem `
# -ApiKey $env:NUGET_API_KEY `
# -Source https://api.nuget.org/v3/index.json
# }
# env:
# NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}

- name: Create and publish release
id: create_release
uses: softprops/action-gh-release@v1
with:
name: OpenApi v${{ needs.ci.outputs.latest_version }}
tag_name: v${{ needs.ci.outputs.latest_version }}
# files: |
# NuGet/Microsoft.OpenApi.${{ needs.ci.outputs.latest_version }}.nupkg
# NuGet/Microsoft.OpenApi.Readers.${{ needs.ci.outputs.latest_version }}.nupkg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Built with ❤ by [Pipeline Foundation](https://pipeline.foundation)
81 changes: 81 additions & 0 deletions docs/CI-CD_DOCUMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# CI/CD documentation

## 1. Run workflow manually

1. Go to the project's GitHub repository and click on the **Actions** tab

2. From the "Workflows" list on the left, click on "CI/CD Pipeline"

3. On the right, next to the "This workflow has a workflow_dispatch event trigger" label, click on the "Run workflow" dropdown, make sure the default branch is selected (if not manually changed, should be main or master) in the "Use workflow from" dropdown and click the "Run workflow" button

![Actions_workflow_dispatch](images/Actions_workflow_dispatch.png)

NOTE: **screenshots are only exemplary**

<br>

## 2. Automated NuGet publishing

To setup the automated publishing to NuGet:

1. Go to the repo **Settings** tab -> **Secrets**

2. Add a secret with the name `NUGET_API_KEY` and as value use an API key from NuGet.org that is assigned to the packages for this project

NOTE: the automated NuGet publishing is execute **only** when a release is triggered by the ["Automated versioning" feature](#3-automated-versioning)

<br>

## 3. Automated versioning

Automatically bumps up the GitHub tag in the repo and executes the CD job

Note: **not every commit to your default branch creates a release**

Follow these instructions for any commit (push or PR merge) to your default branch, you would like to execute the automated versioning.

You would need one of three keywords at the start of your commit title. Each of the three keywords corresponds to a number in your release version i.e. v1.2.3. The release versioning uses the ["Conventional Commits" specification](https://www.conventionalcommits.org/en/v1.0.0/):

- "fix: ..." - this keyword corresponds to the last number v1.2.**3**, also known as PATCH;
- "feat: ..." - this keyword corresponds to the middle number v1.**2**.3, also known as MINOR;
- "perf: ..." - this keyword corresponds to the first number v**1**.2.3, also known as MAJOR. In addition, to trigger a MAJOR release, you would need to write "BREAKING CHANGE: ..." in the description of the commit, with an empty line above it to indicate it is in the <footer> portion of the description;

Note: when making a MAJOR release by committing through a terminal, use the multiple line syntax to add the commit title on one line and then adding an empty line, and then adding the "BREAKING CHANGE: " label
<br><br>

#### Examples

Example(fix/PATCH): <br>
`git commit -a -m "fix: this is a PATCH release triggering commit"`
<br>
`git push origin vnext`
<br>
Result: v1.2.3 -> **v1.2.4**
<br>
<br>
<br>
Example(feat/MINOR): <br>
`git commit -a -m "feat: this is a MINOR release triggering commit"`
<br>
`git push origin vnext`
<br>
Result: v1.2.3 -> **v1.3.0**
<br>
<br>
<br>
Example(perf/MAJOR): <br>
`` git commit -a -m "perf: this is a MAJOR release triggering commit ` ``
<br>
&gt;&gt; <br>
&gt;&gt; `BREAKING CHANGE: this is the breaking change"`
<br>
`git push origin vnext`
<br>
Result: v1.2.3 -> **v2.0.0**
<br>
<br>
Note: in the MAJOR release example, the PowerShell multiline syntax ` (backtick) is used. After writing a backtick, a press of the Enter key should open a new line.

#

Built with ❤ by [Pipeline Foundation](https://pipeline.foundation)
Binary file added docs/images/Actions_workflow_dispatch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.