Introduce reusable workflows into versions repositories (#60)

pull/61/head
MaksimZhukov 2 years ago committed by GitHub
parent 896369fc7d
commit 5810329d19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,201 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to
# - build and test new versions of a tool (Go, Node)
# - publish a release with a new tool version
# The GITHUB_TOKEN secret is used to trigger workflow runs and publish releases
name: Generate tool packages
on:
workflow_call:
inputs:
tool-name:
description: "Tool name to build and upload. Supported values are: 'go' and 'node'"
required: true
type: string
tool-version:
description: "Tool version to build and upload"
required: true
type: string
publish-release:
description: "Whether to publish releases"
required: true
type: boolean
defaults:
run:
shell: pwsh
jobs:
build:
name: Build ${{ inputs.tool-name }} ${{ inputs.tool-version }} [${{ matrix.platform }}]
runs-on: ubuntu-latest
env:
ARTIFACT_NAME: ${{ inputs.tool-name }}-${{ inputs.tool-version }}-${{ matrix.platform }}-x64
strategy:
fail-fast: false
matrix:
platform: [linux, darwin, win32]
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Build ${{ inputs.tool-name }} ${{ inputs.tool-version }}
run: |
./builders/build-${{ inputs.tool-name }}.ps1 -Version ${{ inputs.tool-version }} `
-Platform ${{ matrix.platform }}
- name: Publish artifact
uses: actions/upload-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ runner.temp }}/artifact
test:
name: Test ${{ inputs.tool-name }} ${{ inputs.tool-version }} [${{ matrix.platform }}]
needs: build
runs-on: ${{ matrix.os }}
env:
ARTIFACT_NAME: ${{ inputs.tool-name }}-${{ inputs.tool-version }}-${{ matrix.platform }}-x64
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux
- os: macos-latest
platform: darwin
- os: windows-latest
platform: win32
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Fully cleanup the toolcache directory before testing
run: ./helpers/clean-toolcache.ps1 -ToolName "${{ inputs.tool-name }}"
- name: Download artifact
uses: actions/download-artifact@v3
with:
path: ${{ runner.temp }}
- name: Extract files
run: |
if ('${{ matrix.platform }}' -eq 'win32') {
if ('${{ inputs.tool-name }}' -eq 'node') {
$artifactName = "${{ env.ARTIFACT_NAME }}.7z"
} elseif ('${{ inputs.tool-name }}' -eq 'go') {
$artifactName = "${{ env.ARTIFACT_NAME }}.zip"
} else {
Write-Host "Unsupported tool - ${{ inputs.tool-name }}"
exit 1
}
7z.exe x "$artifactName" -y | Out-Null
} else {
$artifactName = "${{ env.ARTIFACT_NAME }}.tar.gz"
tar -xzf $artifactName
}
working-directory: ${{ runner.temp }}/${{ env.ARTIFACT_NAME }}
- name: Apply build artifact to the local machine
run: |
if ('${{ matrix.platform }}' -eq 'win32') { powershell ./setup.ps1 } else { sh ./setup.sh }
working-directory: ${{ runner.temp }}/${{ env.ARTIFACT_NAME }}
- name: Setup Node.js ${{ inputs.tool-version }}
if: inputs.tool-name == 'node'
uses: actions/setup-node@v3
with:
node-version: ${{ inputs.tool-version }}
- name: Setup Go ${{ inputs.tool-version }}
if: inputs.tool-name == 'go'
uses: actions/setup-go@v3
with:
go-version: ${{ inputs.tool-version }}
- name: Wait for the logs
run: |
Write-Host "Fake step that does nothing"
Write-Host "We need it because log from the previous step 'Setup ${{ inputs.tool-name }}' is not available here yet."
Write-Host "In testing step we analyze build log of 'Setup ${{ inputs.tool-name }}' task"
Write-Host "to determine if ${{ inputs.tool-name }} version was consumed from cache or if it was downloaded"
for ($i = 0; $i -lt 200; $i++) { Get-Random }
- name: Run tests
env:
VERSION: ${{ inputs.tool-version }}
run: |
Install-Module Pester -Force -Scope CurrentUser
Import-Module Pester
$toolName = (Get-Culture).TextInfo.ToTitleCase("${{ inputs.tool-name }}")
Invoke-Pester -Script ./$toolName.Tests.ps1 -EnableExit
working-directory: ./tests
publish_release:
name: Publish release
if: inputs.publish-release
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
- name: Generate release body
id: generate-release-body
run: |
if ('${{ inputs.tool-name }}' -eq 'node') {
$releaseBody = 'Node.js ${{ inputs.tool-version }}'
} else {
$releaseBody = 'Go ${{ inputs.tool-version }}'
}
echo "RELEASE_BODY=$releaseBody" >> $env:GITHUB_OUTPUT
- name: Publish Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ inputs.tool-version }}-${{ github.run_id }}
release_name: ${{ inputs.tool-version }}
body: |
${{ steps.generate-release-body.outputs.RELEASE_BODY }}
- name: Upload release assets
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
for (let artifactDir of fs.readdirSync('.')) {
let artifactName = fs.readdirSync(`${artifactDir}`)[0];
console.log(`Upload ${artifactName} asset`);
github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: ${{ steps.create_release.outputs.id }},
name: artifactName,
data: fs.readFileSync(`./${artifactDir}/${artifactName}`)
});
}
trigger_pr:
name: Trigger "Create Pull Request" workflow
needs: publish_release
runs-on: ubuntu-latest
steps:
- name: Trigger "Create Pull Request" workflow
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'create-pr.yml',
ref: 'main'
});

@ -0,0 +1,43 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to create a PR with update of versions-manifest.json when a new release is published
# The GITHUB_TOKEN secret is used to create versions-manifest.json and publish related PR
name: Create Pull Request
on:
workflow_call:
inputs:
tool-name:
description: 'Name of the tool for which PR is created'
required: true
type: string
defaults:
run:
shell: pwsh
jobs:
create_pr:
name: Create Pull Request
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Create versions-manifest.json
run: |
./helpers/packages-generation/manifest-generator.ps1 -RepositoryFullName "$env:GITHUB_REPOSITORY" `
-GitHubAccessToken "${{ secrets.GITHUB_TOKEN }}" `
-OutputFile "./versions-manifest.json" `
-ConfigurationFile "./config/${{ inputs.tool-name }}-manifest-config.json"
- name: Create GitHub PR
run: |
$formattedDate = Get-Date -Format "MM/dd/yyyy"
./helpers/github/create-pull-request.ps1 `
-RepositoryFullName "$env:GITHUB_REPOSITORY" `
-AccessToken "${{ secrets.GITHUB_TOKEN }}" `
-BranchName "update-versions-manifest-file" `
-CommitMessage "Update versions-manifest" `
-PullRequestTitle "[versions-manifest] Update for release from ${formattedDate}" `
-PullRequestBody "Update versions-manifest.json for release from ${formattedDate}"

@ -0,0 +1,109 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to check for new versions of a tool (Python, Node, etc.)
# The 'SLACK_CHANNEL_URL' secret must be added to the repository containing the caller workflow
# in order to publish messages to Slack.
# The 'Get Available Tools Versions - Publishing Approval' environment must be created in the repository containing the caller workflow
# The 'trigger_builds' job requires manual approval
# The GITHUB_TOKEN secret is used to cancel and trigger workflow runs
name: Get new tool versions
on:
workflow_call:
inputs:
tool-name:
description: 'Name of the tool for which versions are searched'
required: true
type: string
image-url:
description: 'Tool image to be attached to Slack posts'
required: true
type: string
defaults:
run:
shell: pwsh
jobs:
find_new_versions:
name: Find new versions
runs-on: ubuntu-latest
outputs:
versions_output: ${{ steps.Get_new_versions.outputs.TOOL_VERSIONS }}
steps:
- uses: actions/checkout@v3
with:
submodules: true
- id: Get_new_versions
name: Get new versions
run: ./helpers/get-new-tool-versions/get-new-tool-versions.ps1 -ToolName ${{ inputs.tool-name }}
check_new_versions:
name: Check new versions
runs-on: ubuntu-latest
needs: find_new_versions
env:
TOOL_VERSIONS: ${{needs.find_new_versions.outputs.versions_output}}
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Check Versions
if: env.TOOL_VERSIONS == ''
run: |
Write-Host "No new versions were found"
Import-Module "./helpers/github/github-api.psm1"
$gitHubApi = Get-GitHubApi -RepositoryFullName "$env:GITHUB_REPOSITORY" `
-AccessToken "${{ secrets.GITHUB_TOKEN }}"
$gitHubApi.CancelWorkflow("$env:GITHUB_RUN_ID")
Start-Sleep -Seconds 60
- name: Send Slack notification
run: |
$pipelineUrl = "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID"
$message = "The following versions of '${{ inputs.tool-name }}' are available to upload: ${{ env.TOOL_VERSIONS }}\nLink to the pipeline: $pipelineUrl"
./helpers/get-new-tool-versions/send-slack-notification.ps1 -Url "${{ secrets.SLACK_CHANNEL_URL }}" `
-ToolName "${{ inputs.tool-name }}" `
-ImageUrl "${{ inputs.image-url }}" `
-Text "$message"
trigger_builds:
name: Trigger builds
runs-on: ubuntu-latest
needs: [find_new_versions, check_new_versions]
env:
TOOL_VERSIONS: ${{needs.find_new_versions.outputs.versions_output}}
environment: Get Available Tools Versions - Publishing Approval
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Trigger "Build ${{ inputs.tool-name }} packages" workflow
run: |
$workflowFileName = "build-${{ inputs.tool-name }}-packages.yml".ToLower()
./helpers/github/run-ci-builds.ps1 -RepositoryFullName "$env:GITHUB_REPOSITORY" `
-AccessToken "${{ secrets.GITHUB_TOKEN }}" `
-WorkflowFileName "$workflowFileName" `
-WorkflowDispatchRef "main" `
-ToolVersions "${{ env.TOOL_VERSIONS }}" `
-PublishReleases "true"
check_build:
name: Check build for failures
runs-on: ubuntu-latest
needs: [find_new_versions, check_new_versions, trigger_builds]
if: failure()
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Send Slack notification if build fails
run: |
$pipelineUrl = "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID"
$message = "The build of the '${{ inputs.tool-name }}' detection pipeline failed :progress-error:\nLink to the pipeline: $pipelineUrl"
./helpers/get-new-tool-versions/send-slack-notification.ps1 -Url "${{ secrets.SLACK_CHANNEL_URL }}" `
-ToolName "${{ inputs.tool-name }}" `
-Text "$message" `
-ImageUrl "${{ inputs.image-url }}"

@ -0,0 +1,51 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to validate the versions-manifest.json file
# The 'SLACK_CHANNEL_URL' secret must be added to the repository containing the caller workflow
# in order to publish messages to Slack
name: Validate manifest
on:
workflow_call:
inputs:
tool-name:
description: 'Name of the tool for which manifest is validated'
required: true
type: string
image-url:
description: 'Tool image to be attached to Slack posts'
required: true
type: string
defaults:
run:
shell: pwsh
jobs:
validation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Validate manifest
run: .\helpers\packages-generation\manifest-validator.ps1 -ManifestPath '.\versions-manifest.json'
check_build:
name: Check validation for failures
runs-on: ubuntu-latest
needs: [validation]
if: failure()
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Send Slack notification if validation fails
run: |
$pipelineUrl = "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID"
$message = "The validation of ${{ inputs.tool-name }} manifest failed. \nLink to the pipeline: $pipelineUrl"
.\helpers\get-new-tool-versions\send-slack-notification.ps1 -Url "${{ secrets.SLACK_CHANNEL_URL }}" `
-ToolName "${{ inputs.tool-name }}" `
-Text "$message" `
-ImageUrl "${{ inputs.image-url }}"
Loading…
Cancel
Save