Initial commit

This commit is contained in:
Begona Guereca
2022-07-27 09:43:52 -07:00
commit 50784cbbd1
26 changed files with 1779 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
{
"name": "Codespace to bootstrap valet in a Codespace",
//Use base codespace image then pull Valet on postCreateCommand,
"image": "mcr.microsoft.com/vscode/devcontainers/universal:linux",
"remoteUser": "codespace",
"overrideCommand": false,
"mounts": ["source=codespaces-linux-var-lib-docker,target=/var/lib/docker,type=volume"],
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined",
"--privileged",
"--init"
],
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-azuretools.vscode-docker",
],
"onCreateCommand": 'echo "export GITHUB_ACCESS_TOKEN=$VALET_GHCR_PASSWORD" >> ~/.bashrc',
"postCreateCommand": "sudo bash .devcontainer/setupcodespace.sh ${VALET_GHCR_PASSWORD} ${AZURE_DEVOPS_PROJECT} ${AZURE_DEVOPS_ORGANIZATION} ${AZURE_DEVOPS_ACCESS_TOKEN} ${GITHUB_USER} 'https://github.com/' && gh extension install github/gh-valet || echo 'Could not auto-build. Skipping.' "
}
+28
View File
@@ -0,0 +1,28 @@
#!/bin/bash
echo "Starting setupcodespace.sh"
azdoProject="AZURE_DEVOPS_PROJECT="
azdoOrg="AZURE_DEVOPS_ORGANIZATION="
azdoInstance="AZURE_DEVOPS_INSTANCE_URL="
ghAccess="GITHUB_ACCESS_TOKEN="
azdoAccess="AZURE_DEVOPS_ACCESS_TOKEN="
ghInstanceUrl="GITHUB_INSTANCE_URL="
if [ -z "$1" -o -z "$5" ]
then
echo "Error: Docker Pull Valet not executing because GITHUB_USER and/or VALET_PASSWORD not set"
else
docker login ghcr.io/valet-customers --username $5 --password $1
docker pull ghcr.io/valet-customers/valet-cli:latest
echo "Success: Docker Pull Valet completed"
fi
value=`cat valet/.env.local.template`
echo "$value" > valet/.env.local
if [ -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" -o -z "$6" ]
then
echo "Error: Set envars not set, valid values not passed in. You will have to manually use the valet/.env.local folder"
fi
echo "Finished setupcodespace.sh"
+35
View File
@@ -0,0 +1,35 @@
# This is a workflow to set up an Azure DevOps instance seeded with pipelines
# You need to Add a secret for an Azure DevOps PAT called AZDOPAT
name: Valet Bootstrap for Azure DevOps
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
inputs:
AzDoOrgName:
description: 'Azure DevOps organization name'
required: true
type: string
AzDoUserName:
description: 'Azure DevOps user name'
required: true
type: string
AzDoProjectName:
description: 'Azure DevOps project name'
default: 'ValetBootstrap'
type: string
jobs:
bootstrap:
name: Bootstrap
runs-on: windows-latest
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: Run powershell file to bootstrap Azure DevOps
env:
AZDOPATTOUSE: ${{ secrets.AZURE_DEVOPS_ACCESS_TOKEN }}
ROOTFOLDER: ${{ github.workspace }}
shell: pwsh
run: |
./azure_devops/bootstrap/azDevOps.ps1 -project ${{ github.event.inputs.AzDoProjectName }} -userName ${{ github.event.inputs.AzDoUserName }} -repoName ${{ github.event.inputs.AzDoProjectName }} -orgToUse ${{ github.event.inputs.AzDoOrgName }} -rootFolder $env:ROOTFOLDER -daPassword $env:AZDOPATTOUSE
+353
View File
@@ -0,0 +1,353 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# valet files
valet/.env*local
+235
View File
@@ -0,0 +1,235 @@
param (
$project = "ValetBootstrap",
$repoName = "ValetBootstrap",
$codeFolder= "code,azure_devops/pipelines",
$rootFolder= ".",
$pipelinesRoot="azure_devops/pipelines",
[String]$orgToUse = "..",
[String]$userName=$(Throw "Azure DevOps Username required."),
[String]$daPassword=$(Throw "Password required.")
)
Write-Host "Start Valet Bootstrap"
Write-Host "Azure DevOps Organization to use $orgToUse"
Write-Host "Azure DevOps Project to use $project"
Write-Host "Repo Name $repoName"
Write-Host "Code Folders: $codeFolder"
Write-Host "Root Folders: $rootFolder"
Write-Host "Pipelines Folders: $pipelinesRoot"
Write-Host "Azure DevOps username to authenticate with $userName"
Write-Host "Azure DevOps PAT to authenticate with $daPassword"
function Get-BasicAuthCreds {
param([string]$Username,[String]$Password)
$AuthString = "{0}:{1}" -f $Username,$Password
$AuthBytes = [System.Text.Encoding]::Ascii.GetBytes($AuthString)
return [Convert]::ToBase64String($AuthBytes)
}
#Get the creds to use in all GitHub API calls.
$BasicCreds = Get-BasicAuthCreds -Username "$userName" -Password $daPassword
##########################################################################
#CREATE THE AZURE DEVOPS PROJECT
$createtUrlToUse = [string]::Format("https://dev.azure.com/{0}/_apis/projects?api-version=6.0", $orgToUse)
$projectToCreate = @{
"name"= "$project"
"description"= "Project to be used for Valet Demos"
"capabilities"= @{
"versioncontrol"= @{
"sourceControlType"= "Git"
}
"processTemplate"= @{
"templateTypeId"= "6b724908-ef14-45cf-84f8-768b5384da45"
}
}
}
try{
$projectResponse = Invoke-RestMethod -Method 'Post' -Uri $createtUrlToUse -Headers @{"Authorization"="Basic $BasicCreds"} -Body ($projectToCreate|ConvertTo-Json) -ContentType "application/json"
$projectResponse | ConvertTo-Json
Start-Sleep -s 5
Write-Host "Yes! Project $project was created!"
} Catch {
Write-Host " "
Write-Host "##########################################################################"
Write-Host "ERROR during project creation: $project"
Write-Host "The API call was: $createtUrlToUse"
Write-Host " "
if($_.ErrorDetails.Message) {
Write-Host "See error message below:"
Write-Host $_.ErrorDetails.Message
} else {
Write-Host $_
Write-Host "It is likely that the AZURE_DEVOPS_ACCESS_TOKEN is not set correctly in the worflow OR does not have sufficent permissions"
}
Write-Host " "
Write-Host "##########################################################################"
throw "Exiting. The Project $project was NOT created in Azure DevOps"
}
##########################################################################
# IMPORT THE REPO
Set-Location $rootFolder
[array]$folderArray = $codeFolder.Split(",")
$addTextFile = @{
"refUpdates"= @(
@{
"name"= "refs/heads/main"
"oldObjectId"= "0000000000000000000000000000000000000000"
}
)
"commits"= @(
@{
"comment"= "Initial commit."
"changes"= @(
foreach ($folder in $folderArray)
{
$codeRootFolder = Join-Path -Path $rootFolder -ChildPath $folder
Write-Host "codeRootFolder: $codeRootFolder"
$itemPath = $folder.Substring($folder.lastIndexOf('/') + 1)
Write-Host "itemPath: $itemPath"
$codeFiles = (Get-ChildItem "$codeRootFolder" -Recurse -Attributes !Directory)
foreach ($codeFile in $codeFiles ) {
$daFullName = $codeFile.FullName
$codeBody = (Get-Content "$daFullName" -Raw)
#Write-Host "codeBody: $codeBody"
#Write-Host "folder: $folder"
$relath = $daFullName | Resolve-Path -Relative
#Write-Host "relath: $relath"
$replaceSlash = $folder.Replace("/", "\")
$repoPath = $relath.Substring($relath.lastIndexOf($replaceSlash) + $replaceSlash.Length)
$wholeRepoPath = Join-Path -Path $itemPath -ChildPath $repoPath
$wholeRepoPath = $wholeRepoPath.Replace("\", "/")
#Write-Host "wholeRepoPath: $wholeRepoPath"
#Write-Host "repoPath: $repoPath"
@{
"changeType"= "add"
"item"= @{
"path"= "/$wholeRepoPath"
}
"newContent"= @{
"content"= "$codeBody"
"contentType"= "rawtext"
}
}
}
}
)
}
)
}
try{
$repoUrlToUse = [string]::Format("https://dev.azure.com/{0}/{2}/_apis/git/repositories/{1}/pushes?api-version=7.1-preview.2", $orgToUse, $repoName, $project)
$pushResponse = Invoke-RestMethod -Method 'Post' -Uri $repoUrlToUse -Headers @{"Authorization"="Basic $BasicCreds"} -Body ($addTextFile|ConvertTo-Json -Depth 5) -ContentType "application/json"
$repoIds = $pushResponse.repository.id
Write-Host "Yes! Repo Was was created! The repoId is $repoIds"
} Catch {
Write-Host " "
Write-Host "##########################################################################"
Write-Host "ERROR during Repo creation:"
Write-Host "The API call was: $repoUrlToUse"
Write-Host " "
if($_.ErrorDetails.Message) {
Write-Host "See error message below:"
Write-Host $_.ErrorDetails.Message
} else {
Write-Host $_
}
Write-Host " "
Write-Host "##########################################################################"
throw "Exiting. The Repo was NOT created. It is likely the Project was created in Azure DevOps."
}
##########################################################################
##########################################################################
# Create YML Pipelines
$plUrlToUse = [string]::Format("https://dev.azure.com/{0}/{1}/_apis/pipelines?api-version=6.0-preview.1", $orgToUse, "$project")
$files = Get-ChildItem ".\$pipelinesRoot\yml\"
foreach ($f in $files)
{
$nameOfPl = $f.BaseName
$fileName = $f.Name
Write-Host "basename: $nameOfPl filename: $fileName"
$pipelineCreateBody = @{
"folder"= "pipelines"
"name"= "$nameOfPl"
"configuration"= @{
"type"= "yaml"
"path"= "/pipelines/yml/$fileName"
"repository"= @{
"id"= "$repoIds"
"name"= "$repoName"
"type"= "azureReposGit"
}
}
}
try{
$repoResponse = Invoke-RestMethod -Method 'Post' -Uri $plUrlToUse -Headers @{"Authorization"="Basic $BasicCreds"} -Body ($pipelineCreateBody|ConvertTo-Json) -ContentType "application/json"
} Catch {
Write-Host " "
Write-Host "##########################################################################"
Write-Host "ERROR during Pipeline creation:"
Write-Host "The API call was: $plUrlToUse"
Write-Host " "
if($_.ErrorDetails.Message) {
Write-Host "See error message below:"
Write-Host $_.ErrorDetails.Message
} else {
Write-Host $_
}
Write-Host " "
Write-Host "The Pipeline $nameOfPl was NOT created."
Write-Host "##########################################################################"
}
}
##########################################################################
#CREATE CLASSIC PIPELINEs
$classicUrlToUse = [string]::Format("https://dev.azure.com/{0}/{1}/_apis/build/definitions?api-version=7.1-preview.7", $orgToUse, "$project")
$files = Get-ChildItem ".\$pipelinesRoot\classic\"
foreach ($f in $files)
{
$nameOfPl = $f.BaseName
$fileName = $f.Name
Write-Host "basename: $nameOfPl filename: $fileName"
$pclassicreateBody = (Get-Content ./$pipelinesRoot/classic/$fileName).Replace("REPOTOREPLACE", "$repoName")
try{
Invoke-RestMethod -Method 'Post' -Uri $classicUrlToUse -Headers @{"Authorization"="Basic $BasicCreds"} -Body ($pclassicreateBody) -ContentType "application/json"
} Catch {
Write-Host " "
Write-Host "##########################################################################"
Write-Host "ERROR during Pipeline creation:"
Write-Host "The API call was: $classicUrlToUse"
Write-Host " "
if($_.ErrorDetails.Message) {
Write-Host "See error message below:"
Write-Host $_.ErrorDetails.Message
} else {
Write-Host $_
}
Write-Host " "
Write-Host "The Pipeline $nameOfPl was NOT created."
Write-Host "##########################################################################"
}
}
Write-Host "End Valet Bootstrap"
@@ -0,0 +1,243 @@
{
"options": [
{
"enabled": true,
"definition": {
"id": "5d58cc01-7c75-450c-be18-a388ddb129ec"
},
"inputs": {
"branchFilters": "[\"+refs/heads/*\"]",
"additionalFields": "{}"
}
},
{
"enabled": false,
"definition": {
"id": "a9db38f9-9fdc-478c-b0f9-464221e58316"
},
"inputs": {
"workItemType": "Task",
"assignToRequestor": "true",
"additionalFields": "{}"
}
}
],
"variables": {
"BuildConfiguration": {
"value": "release",
"allowOverride": true
},
"BuildPlatform": {
"value": "any cpu",
"allowOverride": true
},
"system.debug": {
"value": "false",
"allowOverride": true
}
},
"properties": {},
"tags": [],
"_links": [],
"buildNumberFormat": "$(date:yyyyMMdd)$(rev:.r)",
"jobAuthorizationScope": 1,
"jobTimeoutInMinutes": 60,
"jobCancelTimeoutInMinutes": 5,
"process": {
"phases": [
{
"steps": [
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Use NuGet 4.4.1",
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"condition": "succeeded()",
"task": {
"id": "2c65196a-54fd-4a02-9be8-d9d1837b7c5d",
"versionSpec": "0.*",
"definitionType": "task"
},
"inputs": {
"versionSpec": "4.4.1",
"checkLatest": "false"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "NuGet restore",
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"condition": "succeeded()",
"task": {
"id": "333b11bd-d341-40d9-afcf-b32d5ce6f23b",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"command": "restore",
"solution": "$(Parameters.solution)",
"selectOrConfig": "select",
"feedRestore": "",
"includeNuGetOrg": "true",
"nugetConfigPath": "",
"externalEndpoints": "",
"noCache": "false",
"disableParallelProcessing": "false",
"packagesDirectory": "",
"verbosityRestore": "Detailed",
"searchPatternPush": "$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg",
"nuGetFeedType": "internal",
"feedPublish": "",
"publishPackageMetadata": "true",
"allowPackageConflicts": "false",
"externalEndpoint": "",
"verbosityPush": "Detailed",
"searchPatternPack": "**/*.csproj",
"configurationToPack": "$(BuildConfiguration)",
"outputDir": "$(Build.ArtifactStagingDirectory)",
"versioningScheme": "off",
"includeReferencedProjects": "false",
"versionEnvVar": "",
"requestedMajorVersion": "1",
"requestedMinorVersion": "0",
"requestedPatchVersion": "0",
"packTimezone": "utc",
"includeSymbols": "false",
"toolPackage": "false",
"buildProperties": "",
"basePath": "",
"verbosityPack": "Detailed",
"arguments": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "PowerShell Script",
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"condition": "succeeded()",
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"targetType": "inline",
"filePath": "",
"arguments": "",
"script": "# Write your PowerShell commands here.\n\nWrite-Host \"Hello World\"\n",
"errorActionPreference": "stop",
"warningPreference": "default",
"informationPreference": "default",
"verbosePreference": "default",
"debugPreference": "default",
"failOnStderr": "false",
"showWarnings": "false",
"ignoreLASTEXITCODE": "false",
"pwsh": "false",
"workingDirectory": "",
"runScriptInSeparateScope": "false"
}
}
],
"name": "Agent job 1",
"refName": "Job_1",
"condition": "succeeded()",
"target": {
"executionOptions": {
"type": 0
},
"allowScriptsAuthAccessOption": false,
"type": 1
},
"jobAuthorizationScope": 1
}
],
"target": {
"agentSpecification": {
"identifier": "windows-latest"
}
},
"type": 1
},
"repository": {
"properties": {
"cleanOptions": "0",
"labelSources": "0",
"labelSourcesFormat": "$(build.buildNumber)",
"reportBuildStatus": "true",
"gitLfsSupport": "false",
"skipSyncSource": "false",
"checkoutNestedSubmodules": "false",
"fetchDepth": "0"
},
"id": "",
"type": "TfsGit",
"name": "REPOTOREPLACE",
"url": "",
"defaultBranch": "refs/heads/main",
"clean": "false",
"checkoutSubmodules": false
},
"processParameters": {
"inputs": [
{
"aliases": [],
"options": {},
"properties": {},
"name": "solution",
"label": "Solution",
"defaultValue": "**\\*.sln",
"required": true,
"type": "filePath",
"helpMarkDown": "The path to the Visual Studio solution file or NuGet packages.config. Wildcards can be used. For example, `**\\\\*.sln` for all sln files in all sub folders."
}
]
},
"quality": 1,
"authoredBy": {
"displayName": "David Kalmin",
"url": "https://spsprodcus5.vssps.visualstudio.com/A8ceff4ff-6429-4de3-9c39-fd7f0b1fb05a/_apis/Identities/a886d3a4-5700-6920-a3e4-6dadf46e7614",
"_links": {
"avatar": {
"href": "https://dev.azure.com/microsoft-bootcamp/_apis/GraphProfile/MemberAvatars/aad.YTg4NmQzYTQtNTcwMC03OTIwLWEzZTQtNmRhZGY0NmU3NjE0"
}
},
"id": "a886d3a4-5700-6920-a3e4-6dadf46e7614",
"uniqueName": "[email protected]",
"imageUrl": "https://dev.azure.com/microsoft-bootcamp/_apis/GraphProfile/MemberAvatars/aad.YTg4NmQzYTQtNTcwMC03OTIwLWEzZTQtNmRhZGY0NmU3NjE0",
"descriptor": "aad.YTg4NmQzYTQtNTcwMC03OTIwLWEzZTQtNmRhZGY0NmU3NjE0"
},
"drafts": [],
"queue": {
"_links": {
"self": {
"href": "https://dev.azure.com/microsoft-bootcamp/_apis/build/Queues/126"
}
},
"name": "Azure Pipelines",
"url": "https://dev.azure.com/microsoft-bootcamp/_apis/build/Queues/126",
"pool": {
"name": "Azure Pipelines",
"isHosted": true
}
},
"id": 10,
"name": "valet-classic-test-import1",
"uri": "vstfs:///Build/Definition/10",
"path": "\\",
"type": 2,
"queueStatus": 0,
"revision": 1,
"createdDate": "2022-02-17T19:05:52.500Z",
}
@@ -0,0 +1,243 @@
{
"options": [
{
"enabled": true,
"definition": {
"id": "5d58cc01-7c75-450c-be18-a388ddb129ec"
},
"inputs": {
"branchFilters": "[\"+refs/heads/*\"]",
"additionalFields": "{}"
}
},
{
"enabled": false,
"definition": {
"id": "a9db38f9-9fdc-478c-b0f9-464221e58316"
},
"inputs": {
"workItemType": "Task",
"assignToRequestor": "true",
"additionalFields": "{}"
}
}
],
"variables": {
"BuildConfiguration": {
"value": "release",
"allowOverride": true
},
"BuildPlatform": {
"value": "any cpu",
"allowOverride": true
},
"system.debug": {
"value": "false",
"allowOverride": true
}
},
"properties": {},
"tags": [],
"_links": [],
"buildNumberFormat": "$(date:yyyyMMdd)$(rev:.r)",
"jobAuthorizationScope": 1,
"jobTimeoutInMinutes": 60,
"jobCancelTimeoutInMinutes": 5,
"process": {
"phases": [
{
"steps": [
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Use NuGet 4.4.1",
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"condition": "succeeded()",
"task": {
"id": "2c65196a-54fd-4a02-9be8-d9d1837b7c5d",
"versionSpec": "0.*",
"definitionType": "task"
},
"inputs": {
"versionSpec": "4.4.1",
"checkLatest": "false"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "NuGet restore",
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"condition": "succeeded()",
"task": {
"id": "333b11bd-d341-40d9-afcf-b32d5ce6f23b",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"command": "restore",
"solution": "$(Parameters.solution)",
"selectOrConfig": "select",
"feedRestore": "",
"includeNuGetOrg": "true",
"nugetConfigPath": "",
"externalEndpoints": "",
"noCache": "false",
"disableParallelProcessing": "false",
"packagesDirectory": "",
"verbosityRestore": "Detailed",
"searchPatternPush": "$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg",
"nuGetFeedType": "internal",
"feedPublish": "",
"publishPackageMetadata": "true",
"allowPackageConflicts": "false",
"externalEndpoint": "",
"verbosityPush": "Detailed",
"searchPatternPack": "**/*.csproj",
"configurationToPack": "$(BuildConfiguration)",
"outputDir": "$(Build.ArtifactStagingDirectory)",
"versioningScheme": "off",
"includeReferencedProjects": "false",
"versionEnvVar": "",
"requestedMajorVersion": "1",
"requestedMinorVersion": "0",
"requestedPatchVersion": "0",
"packTimezone": "utc",
"includeSymbols": "false",
"toolPackage": "false",
"buildProperties": "",
"basePath": "",
"verbosityPack": "Detailed",
"arguments": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "PowerShell Script",
"timeoutInMinutes": 0,
"retryCountOnTaskFailure": 0,
"condition": "succeeded()",
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"targetType": "inline",
"filePath": "",
"arguments": "",
"script": "# Write your PowerShell commands here.\n\nWrite-Host \"Hello World\"\n",
"errorActionPreference": "stop",
"warningPreference": "default",
"informationPreference": "default",
"verbosePreference": "default",
"debugPreference": "default",
"failOnStderr": "false",
"showWarnings": "false",
"ignoreLASTEXITCODE": "false",
"pwsh": "false",
"workingDirectory": "",
"runScriptInSeparateScope": "false"
}
}
],
"name": "Agent job 1",
"refName": "Job_1",
"condition": "succeeded()",
"target": {
"executionOptions": {
"type": 0
},
"allowScriptsAuthAccessOption": false,
"type": 1
},
"jobAuthorizationScope": 1
}
],
"target": {
"agentSpecification": {
"identifier": "windows-latest"
}
},
"type": 1
},
"repository": {
"properties": {
"cleanOptions": "0",
"labelSources": "0",
"labelSourcesFormat": "$(build.buildNumber)",
"reportBuildStatus": "true",
"gitLfsSupport": "false",
"skipSyncSource": "false",
"checkoutNestedSubmodules": "false",
"fetchDepth": "0"
},
"id": "",
"type": "TfsGit",
"name": "REPOTOREPLACE",
"url": "",
"defaultBranch": "refs/heads/main",
"clean": "false",
"checkoutSubmodules": false
},
"processParameters": {
"inputs": [
{
"aliases": [],
"options": {},
"properties": {},
"name": "solution",
"label": "Solution",
"defaultValue": "**\\*.sln",
"required": true,
"type": "filePath",
"helpMarkDown": "The path to the Visual Studio solution file or NuGet packages.config. Wildcards can be used. For example, `**\\\\*.sln` for all sln files in all sub folders."
}
]
},
"quality": 1,
"authoredBy": {
"displayName": "David Kalmin",
"url": "https://spsprodcus5.vssps.visualstudio.com/A8ceff4ff-6429-4de3-9c39-fd7f0b1fb05a/_apis/Identities/a886d3a4-5700-6920-a3e4-6dadf46e7614",
"_links": {
"avatar": {
"href": "https://dev.azure.com/microsoft-bootcamp/_apis/GraphProfile/MemberAvatars/aad.YTg4NmQzYTQtNTcwMC03OTIwLWEzZTQtNmRhZGY0NmU3NjE0"
}
},
"id": "a886d3a4-5700-6920-a3e4-6dadf46e7614",
"uniqueName": "[email protected]",
"imageUrl": "https://dev.azure.com/microsoft-bootcamp/_apis/GraphProfile/MemberAvatars/aad.YTg4NmQzYTQtNTcwMC03OTIwLWEzZTQtNmRhZGY0NmU3NjE0",
"descriptor": "aad.YTg4NmQzYTQtNTcwMC03OTIwLWEzZTQtNmRhZGY0NmU3NjE0"
},
"drafts": [],
"queue": {
"_links": {
"self": {
"href": "https://dev.azure.com/microsoft-bootcamp/_apis/build/Queues/126"
}
},
"name": "Azure Pipelines",
"url": "https://dev.azure.com/microsoft-bootcamp/_apis/build/Queues/126",
"pool": {
"name": "Azure Pipelines",
"isHosted": true
}
},
"id": 10,
"name": "valet-classic-test-import2",
"uri": "vstfs:///Build/Definition/10",
"path": "\\",
"type": 2,
"queueStatus": 0,
"revision": 1,
"createdDate": "2022-02-17T19:05:52.500Z",
}
+10
View File
@@ -0,0 +1,10 @@
# pipelines folder
This folder contains Azure DevOps pipelines that gets migrated to the Azure DevOps instance.
### Note any file added to this folder or sub folders will get migrated to the Azure DevOps instance when the GitHub Action runs to create and bootstrap the Azure DevOps project
## classic folder
The classic folder contains classic style Azure DevOps pipelines that are pure JSON files.
## yml folder
The yml folder contains yml Azure DevOps pipelines.
@@ -0,0 +1,29 @@
---
variables:
- name: BuildParameters.RESTOREBUILDPROJECTS
value: "**/*.csproj"
- name: BUILDCONFIGURATION
value: Release
name: "$(date:yyyyMMdd)$(rev:.r)"
jobs:
- job: Job_1
displayName: Agent job 1
pool:
vmImage: windows-latest
steps:
- checkout: self
- task: NodeTool@0
displayName: Use Node 10.16.3
inputs:
versionSpec: 10.16.3
- task: DotNetCoreCLI@2
displayName: Restore
inputs:
command: restore
projects: "$(BuildParameters.RESTOREBUILDPROJECTS)"
- task: DotNetCoreCLI@2
displayName: Build
inputs:
projects: "$(BuildParameters.RESTOREBUILDPROJECTS)"
arguments: "--configuration $(BUILDCONFIGURATION)"
@@ -0,0 +1,19 @@
# Bootcap Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- main
pool:
vmImage: windows-latest
steps:
- script: echo Hello, I am pipeline 1!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
@@ -0,0 +1,19 @@
# Bootcap Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- main
pool:
vmImage: windows-latest
steps:
- script: echo Hello, I am pipeline 2!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
+133
View File
@@ -0,0 +1,133 @@
# Valet labs for Azure DevOps
This lab bootstraps a Valet environment using GitHub Codespaces and enables you to create an Azure DevOps project against which to run the Valet CI/CD migration tool.
- [Use this Repo as a template](#repo-template)
- [Prerequisites](#prerequisites)
- [Codespace secrets](#codespace-secrets)
- [Action secrets](#action-secrets)
- [Azure DevOps project creation](#azure-devops-project-creation)
- [Use Valet with a codespace](#use-valet-with-a-codespace)
- [Labs for Azure DevOps](#labs-for-azure-devops)
## Repo template
1. Verify you are in your own Repository created from the landing page [Valet Labs](https://github.com/valet-customers/labs).
## Prerequisites
1. Azure DevOps organization. Please identify or create an Azure DevOps organization to use: [Click to create an Azure DevOps Org](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/create-organization?toc=%2Fazure%2Fdevops%2Fget-started%2Ftoc.json&bc=%2Fazure%2Fdevops%2Fget-started%2Fbreadcrumb%2Ftoc.json&view=azure-devops)
- Note and store the Azure DevOp sorganization name for later.
- Note and store the user name you use for your Azure DevOps Organization. It will be an email address.
2. Azure DevOps Project. The default project name for this lab is `ValetBootstrap` There is an Action workflow that will create and populate the Azure DevOps project. No need to create it yourself. Note: The project has to be unique in the Azure DevOps organization. If you already have a project name `ValetBootstrap` please pick a different unique project name.
- Note and store the Azure DevOps project name for later.
3. Create an Azure DevOps personal access token with the following scopes:
- To do so, navigate to Sign in to your organization `https://dev.azure.com/{yourorganization}`.
- Click your `Account management` icon
- Click `user settings`
- Click `Personal access tokens`.
- Select `+ New Token`
- Name your token, select the organization where you want to use the token, and then set your token to automatically expire after a set number of days.
- Select the following scopes (Click `Show more scopes` if you don't see all of the below):
- Agents Pool: `Read`
- Build: `Read & Execute`
- Code: `Read & Write`
- Project and Team: `Read, Write, & Manage`
- Release: `Read`
- Service Connections: `Read`
- Task Groups: `Read`
- Variable Groups: `Read`
- Click `Create`
- Copy the PAT somewhere safe and temporary.
4. Create a GitHub personal access token.
- To do so, navigate to your GitHub `Settings` - click your profile photo and then click `Settings`.
- Go to `Developer Settings`
- Go to `Personal Access Tokens` -> `Legacy tokens (if present)`
- Click `Generate new token` -> `Legacy tokens (if present)`. If required, provide your password.
- Select at least these scopes: `read packages` and `workflow`. Optionally, provide a text in the **Note** field and change the expiration.
- Click `Generate token`
- Copy the PAT somewhere safe and temporary.
## Codespace secrets
Please add the following Codespace secrets.
- `VALET_GHCR_PASSWORD`: Add `VALET_GHCR_PASSWORD` as the `Name` and the GitHub personal access token created above as the value.
- `AZURE_DEVOPS_ACCESS_TOKEN`: Add `AZURE_DEVOPS_ACCESS_TOKEN` as the `Name` and the Azure DevOps personal access token created above as the value.
- `AZURE_DEVOPS_ORGANIZATION`: Add `AZURE_DEVOPS_ORGANIZATION` as the `Name` and the Azure DevOps organization noted above as the value.
- `AZURE_DEVOPS_PROJECT`: Add `AZURE_DEVOPS_PROJECT` as the `Name` and the Azure DevOps project noted above as the value.
Steps to create the Codespace secrets. Complete for secret noted above:
- Navigate to the `Settings` tab in this repo
- Find `Secrets` and click the down arrow
- Click `Codespaces`
- Click `New Repository Secret` to create a new secret
- Name the secret as noted above
- Paste in the value noted above
- Click `Add Secret`
## Action secrets
Please add the following Action secrets.
- `AZURE_DEVOPS_ACCESS_TOKEN`: Add `AZURE_DEVOPS_ACCESS_TOKEN` as the `Name` and the Azure DevOps personal access token created above as the value.
Steps to create the Actions secret. Complete for secret noted above:
- Navigate to the `Settings` tab in this repo
- Find `Secrets` and click the down arrow
- Click `Actions`
- Click `New Repository Secret` to create a new secret
- Name the secret as noted above
- Paste in the value noted above
- Click `Add Secret`
## Azure DevOps project creation
Run the Actions workflow:
- CLick the `Actions` tab
- Select the `Valet Bootstrap for Azure DevOps` action
- Click `Run Workflow`
- Input the Azure DevOps Organization name identified above
- Input the Azure DevOps user name of the user that created the Azure DevOps PAT above. This will be an email address
- Accept the default Azure DevOps project name or change it to one of your preference
- NOTE: The default project name is `ValetBootstrap`. This must be unique in your Azure DevOps Organization. If not, please choose a unique name.
- Click `Run Workflow`
- Verify the workflow completed successfully. If the workflow did not run successfully you will see a detailed error message.
### Example ###
![runaction](https://user-images.githubusercontent.com/26442605/167679930-9bdf6f4f-2e94-4145-aed3-8ee3e8e91d90.png)
## Use Valet with a codespace
1. Start the codespace
- Click the `Code` with button down arrow above repository on the repository's landing page.
- Click the `Codespaces` tab
- Click `Create codespaces on main` to create the codespace. If you are in another branch then the `main` branch, the codespace will button will have the current branch specified.
- Wait a couple minutes, then verify that the codespace starts up. Once it is fully booted up, the termininal should be present.
2. Verify Valet CLI is installed and working. More information on the [GitHub Valet CLI extension](https://github.com/github/gh-valet)
- Verify Valet CLI is installed and working
- Run `gh valet version` in the Visual Studio Code terminal and verify the output looks like the below image. Note the valet version will be different than below as the latest version gets pulled down.
- If `gh valet version` did not produce a similar image with a version please follow these instructions [Troubleshoot GH Valet extension](#troubleshoot-gh-valet-extension)
- Start using Valet by following along with the [Labs for Azure DevOps](#labs-for-azure-devops)
### Example ###
![gh-valet-version](https://user-images.githubusercontent.com/26442605/170106559-e69e669f-a1f6-4c2c-8998-3f089b899704.png)
## Labs for Azure DevOps
Perform the following labs to test-drive Valet
- [Audit Azure DevOps pipelines using the Valet audit command](valet-audit-lab.md)
- [Dry run the migration of an Azure DevOps pipeline to GitHub Actions](valet-dry-run-lab.md)
- [Migrate an Azure DevOps pipeline to GitHub Actions](valet-migrate-lab.md)
- [Migrate an Azure DevOps pipeline to GitHub Actions with a custom transformer](valet-migrate-custom-lab.md)
- [Forecast: Valet forecast lab](valet-forecast-lab.md)
## Troubleshoot GH Valet extension
Manually Install the GitHub CLI Valet extension. More information on the [GitHub Valet CLI extension](https://github.com/github/gh-valet)
- Verify you are in the Visual Studio Code terminal
- Run this command to install the GitHub Valet extension
- `gh extension install github/gh-valet`
- Verify the result of the install is: `✓ Installed extension github/gh-valet`
- If you get a similiar error to the following, click the link to authorize the token
![linktolcickauth](https://user-images.githubusercontent.com/26442605/169588015-9414404f-82b6-4d0f-89d4-5f0e6941b029.png)
- Restart Codespace after clicking the link
- Verify Valet CLI is installed and working
+52
View File
@@ -0,0 +1,52 @@
# Audit Azure DevOps pipelines using the Valet audit command
In this lab, you will use Valet to `audit` an Azure DevOps organization. The `audit` command can be used to scan a CI server and output a summary of the current pipelines. This summary can then be used to plan the timeline and effort required to migrate to GitHub Actions.
- [Prerequisites](#prerequisites)
- [Perform an audit](#perform-an-audit)
- [View audit output](#view-audit-output)
- [Review the pipelines](#review-the-pipelines)
- [Next Lab](#next-lab)
## Prerequisites
1. Follow all steps [here](../azure_devops#readme) to set up your environment
2. Create or start a codespace in this repository (if not started)
## Perform an audit
You will use the codespace preconfigured in this repository to perform the audit.
1. Navigate to the codespace Visual Studio Code terminal
2. Verify you are in the `valet` directory
3. Now, from the `valet` folder in your repository, run Valet to verify your Azure DevOps configuration:
```
gh valet audit azure-devops --output-dir audit
```
### Example
![valet-audit-1](https://user-images.githubusercontent.com/26442605/169615028-696dad13-ff83-41a7-b475-0ab8c0bbcd65.png)
4. Valet displays green log files to indicate a successful audit
### Example
![valet-audit-2](https://user-images.githubusercontent.com/26442605/169615218-a8a3199d-a436-4d70-8c1e-17a61b089eb6.png)
## View audit output
The audit summary, logs, Azure DevOps yml, and GitHub yml should all be located in the `valet` folder.
1. Under the `valet` folder find the `audit_summary.md`
2. Right-click the `audit_summary.md` file and select `Open Preview`
3. The file contains details about your current pipelines and what can be migrated 100% automatically vs. what will need some manual intervention or aren't supported by GitHub Actions.
4. Review the file.
### Example
![valet-audit-3](https://user-images.githubusercontent.com/26442605/169615428-26f7a962-2064-46d0-8206-ea930109b252.png)
## Review the pipelines
The `audit` command grabs the yml, classic, and release pipelines from Azure DevOps and converts them to GitHub Actions.
### Example
View the source yml and the proposed GitHub yml
![valet-audit-4](https://user-images.githubusercontent.com/26442605/169615630-8d700081-c631-4b2a-ab1c-e52503f7838f.png)
### Next Lab
[Dry run the migration of an Azure DevOps pipeline to GitHub Actions](valet-dry-run-lab.md)
+52
View File
@@ -0,0 +1,52 @@
# Dry run the migration of an Azure DevOps pipeline to GitHub Actions
In this lab, you will use the `valet dry-run` command to convert an Azure DevOps pipeline to it's equivalent GitHub Actions workflow and write the workflow to your local filesystem.
- [Prerequisites](#prerequisites)
- [Identify the Azure DevOps pipeline ID to use](#identify-the-azure-devops-pipeline-id-to-use)
- [Perform a dry run](#perform-a-dry-run)
- [View dry-run output](#view-dry-run-output)
- [Next Lab](#next-lab)
## Prerequisites
1. Follow all steps [here](../azure_devops#readme) to set up your environment
2. Create or start a codespace in this repository (if not started)
3. You have completed the [Valet audit lab](valet-audit-lab.md).
## Identify the Azure DevOps pipeline ID to use
You will need a pipeline ID to perform the dry run
1. Go to the `valet/ValetBootstrap/pipelines` folder
2. Open the `valet/ValetBootstrap/pipelines/valet-pipeline1.config.json` file
3. Look for the `$.web.href` link
4. At the end of the link is the pipeline ID. Copy or note the ID.
### Example
![valet-dr-5](https://user-images.githubusercontent.com/26442605/169616920-7c407adc-0c4e-4104-9046-d1d2ecdd6edf.png)
## Perform a dry run
You will use the codespace preconfigured in this repository to perform the dry run.
1. Navigate to the codespace Visual Studio Code terminal
2. Verify you are in the `valet` directory
```
gh valet dry-run azure-devops pipeline --pipeline-id PIPELINE-ID --output-dir dry-run
```
3. Now, from the `valet` folder in your repository, run `gh valet dry-run` to see the output:
### Example
![valet-dr-1](https://user-images.githubusercontent.com/26442605/169616149-46c2d743-47fe-4061-a48a-7f21442624cb.png)
4. Valet will create a folder called `dry-runs` under the `valet` folder that shows what will be migrated.
### Example
![valet-dr-2](https://user-images.githubusercontent.com/26442605/169616265-176a19fd-3071-44fc-bff7-866a172afc57.png)
## View dry-run output
The dry-run output will show you the GitHub Actions yml that will be migrated to GitHub.
### Example
![valet-dr-3](https://user-images.githubusercontent.com/26442605/169616486-fd5512fa-0761-45fe-a252-5b2ef0926a04.png)
### Next Lab
[Migrate an Azure DevOps pipeline to GitHub Actions](valet-migrate-lab.md)
+3
View File
@@ -0,0 +1,3 @@
# Forecast Azure DevOps to GitHub using Valet forecast command
### Coming soon
+87
View File
@@ -0,0 +1,87 @@
# Migrate an Azure DevOps pipeline to GitHub Actions with a custom transformer
In this lab, you will create a custom plugin that transforms some of the existing migration mapping and replaces it with your own mapping. Then use the `migrate` subcommand to migrate the pipeline. The `migrate` subcommand can be used to convert a pipeline to its GitHub Actions equivalent and then create a pull request with the contents.
- [Prerequisites](#prerequisites)
- [Identify the Azure DevOps pipeline ID to use](#identify-the-azure-devops-pipeline-id-to-use)
- [Create a custom transformer](#create-a-custom-transformer)
- [Migrate with a custom transformer](#migrate-with-a-custom-transformer)
- [View the pull request](#view-the-pull-request)
## Prerequisites
1. Follow all steps [here](../azure_devops#readme) to set up your environment
2. Create or start a codespace in this repository (if not started)
3. Complete the [Valet audit lab](valet-audit-lab.md).
4. Complete the [Valet migrate lab](valet-migrate-lab.md).
## Identify the Azure DevOps pipeline ID to use
You will need the `valet-mapper-example` Azure DevOps pipeline ID to perform the migration
1. Go to the `valet/ValetBootstrap/pipelines` folder
2. Open the `valet/ValetBootstrap/pipelines/valet-mapper-example.config.json` file
3. Look for the `web - href` link
4. At the end of the link is the pipeline ID. Copy or note the ID.
### Example
![mapperprops](https://user-images.githubusercontent.com/26442605/175090567-525b97a7-60d2-41b7-9dcd-d559ca1c5bd7.png)
## Create a custom transformer
To create a transformer, you need to create a Ruby file that looks as follows:
``` ruby
transform "azuredevopstaskname" do |item|
# your ruby code here that produces output
end
```
We start by creating a new folder called `plugin` under the `valet` folder in your repository. In there create a file called `DotNetCoreCLI.rb`.
Next change the function name to match the Azure DevOps task name `DotNetCoreCLI@2`.
The way you find this name is by clicking the **view yaml** button at a task in the pipeline:
This results in the following code:
``` ruby
transform "DotNetCoreCLI@2" do |item|
# your ruby code here that produces output
end
```
The parameter item is a collection of items than contain the properties of the original task that was retrieved from Azure DevOps.
In this case we can see in the yaml that the properties that are set are `command` and `projects`.
Add the following code to the ruby file:
``` Ruby
transform "DotNetCoreCLI@2" do |item|
projects = item["projects"]
command = item["command"]
run_command = []
if projects.include?("$")
command = "build" if command.nil?
run_command << "shopt -s globstar; for f in ./**/*.csproj; do dotnet #{command} $f #{item['arguments']} ; done"
else
run_command << "dotnet #{command} #{item['projects']} #{item['arguments']}"
end
{
shell: "bash",
run: run_command.join("\n")
}
end
```
## Migrate with a custom transformer
Run the `gh valet migrate` command from the `valet` directory with the transformer again and pass it the custom plugin. Look at the result and see if it results in a successful build.
```
gh valet migrate azure-devops pipeline --target-url https://github.com/GITHUB-ORG/GITHUB-REPO --pipeline-id PIPELINE-ID --custom-transformers plugin/DotNetCoreCLI.rb --output-dir migrate
```
### Example
![valet-cm-1](https://user-images.githubusercontent.com/26442605/169618556-7c79b34b-6d4c-48d5-98e5-7f8d771117a5.png)
## View the pull request
The migrate output will show you the pull request on GitHub. Note here that the checks on the pull request all passed!
### Example
![mapper-ex3](https://user-images.githubusercontent.com/26442605/161117488-93e38847-3034-4f04-a768-e74e16dba4ae.png)
+59
View File
@@ -0,0 +1,59 @@
# Migrate an Azure DevOps pipeline to GitHub Actions
In this lab, you will use the Valet `migrate` command to migrate an Azure DevOps pipeline to GitHub Actions. The `migrate` subcommand can be used to convert a pipeline to its GitHub Actions equivalent and then create a pull request with the contents.
- [Prerequisites](#prerequisites)
- [Identify the Azure DevOps pipeline ID to use](#identify-the-azure-devops-pipeline-id-to-use)
- [Perform a migration](#perform-a-migration)
- [View the pull request](#view-the-pull-request)
- [Next Lab](#next-lab)
## Prerequisites
1. Follow all steps [here](../azure_devops#readme) to set up your environment
2. Create or start a codespace in this repository (if not started)
3. Completed the [Valet audit lab](valet-audit-lab.md).
## Identify the Azure DevOps pipeline ID to use
You will need a pipeline ID to perform the migration
1. Go to the `valet/ValetBootstrap/pipelines` folder
2. Open the `valet/ValetBootstrap/pipelines/valet-pipeline1.config.json` file
3. Look for the `web - href` link
4. At the end of the link is the pipeline ID. Copy or note the ID.
### Example
![Screen Shot 2022-05-10 at 8 50 06 AM](https://user-images.githubusercontent.com/26442605/167670536-b46aa383-74bd-4e22-a782-0de5d0ce64a5.png)
## Perform a migration
You will use the codespace preconfigured in this repository to perform the migration.
1. Navigate to the codespace Visual Studio Code terminal
2. Verify you are in the valet directory
3. Copy the following command and replace:
- `GITHUB-ORG` with the name of your organization.
- `GITHUB-REPO` with the name of your repository.
- `PIPELINE-ID` with your pipeline ID.
4. Run `gh valet migrate` from the `valet` directory to migrate the pipeline to GitHub Actions..
```
gh valet migrate azure-devops pipeline --target-url https://github.com/GITHUB-ORG/GITHUB-REPO --pipeline-id PIPELINE-ID --output-dir migrate
```
### Example
![valet-migrate-1](https://user-images.githubusercontent.com/26442605/169617557-289cee54-0116-4d13-8e6f-a9d0508259e1.png)
5. Valet will create a pull request directly to your GitHub repository.
6. Click the green pull request link in the output of the migrate command. See below.
### Example
![valet-migrate-5](https://user-images.githubusercontent.com/26442605/169617699-ce0c0720-8830-46ed-811d-c2fe1ccf06ea.png)
## View the pull request
The migrate output will show you the pull request on GitHub.
### Example
![migrate-pr](https://user-images.githubusercontent.com/26442605/161110724-f39d9cb9-1992-44c5-bea5-da2fcebb074c.png)
### Next Lab
[Migrate an Azure DevOps pipeline to GitHub Actions with a custom transformer](valet-migrate-custom-lab.md)
+56
View File
@@ -0,0 +1,56 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B26D43AA-4A35-4035-9E99-48EF9A3E64DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Attendee", "src\Attendee\Attendee.csproj", "{2804EC63-670C-4970-85E4-2A63C9327FF8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{348A52EC-7046-4D1A-88DB-55B025C2BB68}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AttendeeTest", "test\AttendeeTest\AttendeeTest.csproj", "{DED76823-F195-46D4-8509-5692E3431D53}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x64.ActiveCfg = Debug|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x64.Build.0 = Debug|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x86.ActiveCfg = Debug|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x86.Build.0 = Debug|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|Any CPU.Build.0 = Release|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x64.ActiveCfg = Release|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x64.Build.0 = Release|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x86.ActiveCfg = Release|Any CPU
{2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x86.Build.0 = Release|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Debug|x64.ActiveCfg = Debug|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Debug|x64.Build.0 = Debug|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Debug|x86.ActiveCfg = Debug|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Debug|x86.Build.0 = Debug|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Release|Any CPU.Build.0 = Release|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Release|x64.ActiveCfg = Release|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Release|x64.Build.0 = Release|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Release|x86.ActiveCfg = Release|Any CPU
{DED76823-F195-46D4-8509-5692E3431D53}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{2804EC63-670C-4970-85E4-2A63C9327FF8} = {B26D43AA-4A35-4035-9E99-48EF9A3E64DD}
{DED76823-F195-46D4-8509-5692E3431D53} = {348A52EC-7046-4D1A-88DB-55B025C2BB68}
EndGlobalSection
EndGlobal
+5
View File
@@ -0,0 +1,5 @@
# code folder
This folder contains a dotnet core application used for building puproses with the CI/CD selected.
### Note any file added to this folder or sub folders will get migrated to the Azure DevOps instance when the GitHub Action runs to create and bootstrap the Azure DevOps project
+15
View File
@@ -0,0 +1,15 @@
using System;
namespace Attendees
{
public class Attendee
{
public bool AddAttendee(string added)
{
if (added == "exists")
return true;
return false;
}
}
}
+7
View File
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
+18
View File
@@ -0,0 +1,18 @@
using System;
using Xunit;
using Xunit.Extensions;
using Attendees;
namespace AttendeeTest
{
public class AttendeeTest
{
[Fact]
public void AttendeeExistsReturnTrue()
{
Attendee attendee = new Attendee();
bool doesExist = attendee.AddAttendee("doesnotexist");
Assert.False(doesExist, "The attendee does not exist");
}
}
}
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Attendee\Attendee.csproj" />
</ItemGroup>
</Project>
+1
View File
@@ -0,0 +1 @@
# Coming Soon!
+22
View File
@@ -0,0 +1,22 @@
# Welcome to Valet labs!
These Valet labs let you test-drive Valet by bootstrapping the environment of your choosing. To get started:
1. Get access to Valet and create your own GitHub Repository. See [Prerequisites](#prerequisites) below.
2. Bootstrap your environment. The default page of the lab of your choosing will detail how to configure and run the action to bootstrap the environment. Currently these labs support [Azure DevOps](azure_devops).
3. Run Valet via Codespaces. The codespace has docker running and will update to the latest Valet environment.
4. Proceed with running the labs!
# Prerequisites
1. Valet is currently private and customers must be onboarded prior to using it. Please reach out to [GitHub Sales](https://github.com/enterprise/contact) to inquire about being granted access.
2. Create your own GitHub Repository in your own GitHub Organization or under your user with Codespaces enabled using this Repository as a template. To do so:
- Navigate to the top of this Repository click `Use this template`
- Select the owner of the new Reposiotry. It could be your personal username or an Organization you belong to.
- Name the Repository
- Click `Create repository froom template`
- Proceed to the labs inside of your new Repository.
![createtemplate](https://user-images.githubusercontent.com/26442605/174847176-0e515fd3-8107-43e0-af33-70b1ece36d3b.png)
## Environments to bootstrap
- [Azure DevOps](azure_devops)
- [Jenkins](jenkins)
+7
View File
@@ -0,0 +1,7 @@
GITHUB_ACCESS_TOKEN=
GITHUB_INSTANCE_URL=
AZURE_DEVOPS_PROJECT=
AZURE_DEVOPS_ORGANIZATION=
AZURE_DEVOPS_INSTANCE_URL=
AZURE_DEVOPS_ACCESS_TOKEN=