diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9bdc2e9..7aca41f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,10 +1,12 @@ { - "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", + "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"], + "mounts": [ + "source=codespaces-linux-var-lib-docker,target=/var/lib/docker,type=volume" + ], "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", @@ -12,11 +14,10 @@ "--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} ${JENKINS_USERNAME} ${JENKINS_PASSWORD}'https://github.com/' && gh extension install github/gh-valet || echo 'Could not auto-build. Skipping.' " -} + "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.' " +} \ No newline at end of file diff --git a/.devcontainer/setupcodespace.sh b/.devcontainer/setupcodespace.sh index 69ca866..c98469a 100644 --- a/.devcontainer/setupcodespace.sh +++ b/.devcontainer/setupcodespace.sh @@ -25,16 +25,4 @@ then echo "Error: Set envars not set, valid values not passed in. You will have to manually use the valet/.env.local folder" fi - -# if Jenkins codespace secrets are set, spin up Jenkins instance - -if [ -z "$7" -o -z "$8"] -then -else - echo "Jenkins secrets are set, starting Jenkins service" - ../jenkins/jenkins_setup/setupjenkins.sh $7 $8 -fi - - - echo "Finished setupcodespace.sh" diff --git a/.gitignore b/.gitignore index 45805d9..f4adbb6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,6 @@ ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore -.tmp - # User-specific files *.rsuser *.suo diff --git a/azure_devops/pipelines/yml/valet-pipeline3.yml b/azure_devops/pipelines/yml/valet-pipeline3.yml deleted file mode 100644 index d09df8c..0000000 --- a/azure_devops/pipelines/yml/valet-pipeline3.yml +++ /dev/null @@ -1,22 +0,0 @@ -trigger: -- build - -variables: - - name: OLD - value: "SECRET" - -pool: MyPool - -steps: -- script: echo Hello, world! - displayName: 'Run a one-line script' - -- task: GoTool@0 - inputs: - version: '1.10' -- task: AzureFunctionApp@1 - inputs: - azureSubscription: 'ACE CAT: valet-testing' - appType: 'functionAppLinux' - appName: 'demo' - package: '$(System.DefaultWorkingDirectory)/**/*.zip' diff --git a/jenkins/bootstrap/setup.sh b/jenkins/bootstrap/setup.sh new file mode 100755 index 0000000..e7fb5e0 --- /dev/null +++ b/jenkins/bootstrap/setup.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +container_name="valet" +username="admin" +password="password" + +echo "Building Jenkins instance!" + +if [ "$(docker ps -a | grep jenkins:$container_name)" ]; then + echo -e "Jenkins is running" + docker container start jenkins +else + echo -e "\nStarting a new Jenkins container" + # Build jenkins image from docker compose file + docker build -t jenkins:$container_name . + + # Build container + docker run -d --name jenkins -p 8080:8080 --env JENKINS_ADMIN_ID=$username --env JENKINS_ADMIN_PASSWORD=$password jenkins:$container_name +fi + +# allow valet to talk to Jenkins by removing network isolation between containers +export DOCKER_ARGS="--network=host" +grep -q "export DOCKER_ARGS=" ~/.bashrc || echo 'export DOCKER_ARGS="--network=host"' >> ~/.bashrc + +echo -e "\nWaiting for Jenkins to start..." +while ! curl -s http://localhost:8080/ > /dev/null; do + echo -e "." + sleep 5 +done + +echo -e '\nJenkins is up and running!' +echo -e "\nUsername: admin" +echo -e "\bPassword: password" \ No newline at end of file diff --git a/jenkins/readme.md b/jenkins/readme.md index 8349c4a..eb9e71c 100644 --- a/jenkins/readme.md +++ b/jenkins/readme.md @@ -1 +1,71 @@ -# Coming Soon! +# Valet labs for Jenkins + +This lab bootstraps a Valet environment using GitHub Codespaces and enables you to spin up a Jenkins instance against which to run the Valet CI/CD migration tool. + +- [Use this Repo as a template](#repo-template) +- [Prerequisites](#prerequisites) +- [Use Valet with a codespace](#use-valet-with-a-codespace) +- [Bootstrap Jenkins](#bootstrap-jenkins) + +## Repo template + +1. Verify you are in your own Repository created from the landing page [Valet Labs](https://github.com/valet-customers/labs). + + +## 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) + +Screen Shot 2022-08-10 at 1 45 20 PM + +## Bootstrap Jenkins + + 1. Run the Jenkins setup script. This script will setup Jenkins and ensure it is ready to use. In general, this script should be run first if you are starting a new codespace or restarting an existing one. + +- Navigate to the terminal within your Codespace. +- Run `source jenkins/bootstrap/setup.sh` to kick off the creation of your Jenkins instance. +- After a couple seconds, a pop-up box should appear with a link to the forwarded URL for your Jenkins instance. +- You can also access the forwarded URL by going to the `Ports` tab in your terminal. Right click on the URL listed under the `Local Address` and clicking the `Open in Browser` tab. +- Once you have navigated to the url, the following default credentials have been assigned: + + - username: `admin` + - password: `password` + +2. Click the `Sign in` button and you should now see your new Jenkins instance with a few pre-populataed pipelines. + +## Labs for Jenkins + +Perform the following labs to test-drive Valet + +- TBD + +## 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 codespace 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 + - Restart Codespace after clicking the link +- Verify Valet CLI is installed and working by running `gh valet version` + +![linktolcickauth](https://user-images.githubusercontent.com/26442605/169588015-9414404f-82b6-4d0f-89d4-5f0e6941b029.png) + +## Troubleshooting Jenkins + +1. Navigate to the Docker tab on your left hand side. +2. Under the `Containers` tab you should see a Docker container `jenkins:valet` listed with a green play button ▶ + - If you see the `jenkins:valet` container, but it has a red stopped symbol next to it ▢, right click on the container and click on `start`, the container should begin running again. + - If the container does not start even after trying to manually start it, right click on the `jenkins:valet` container and click the `remove` button. Next continue by following all the #bootstrap-jenkins instructions again. + +Screen Shot 2022-08-09 at 3 06 46 PM diff --git a/jenkins/valet-audit-lab.md b/jenkins/valet-audit-lab.md new file mode 100644 index 0000000..cad80e1 --- /dev/null +++ b/jenkins/valet-audit-lab.md @@ -0,0 +1,124 @@ +# Audit Jenkins pipelines using the Valet audit command + +In this lab, you will use Valet to `audit` a Jenkins organization. The `audit` command can be used to scan a CI server and output a summary of the current pipelines. + +What happens behind the scenes is that Valet will perform a `dry-run` on each of the Jenkins pipelines. Once that is complete, Valet will perform an aggregation of all of the transformed workflows. This aggregate summary can be used as a planning tool and help understand how complete of a migration is possible with Valet. + +By the end of this lab you will have performed an audit on the demo Jenkins instance, and have a good understanding of the components that make up an audit. + +- [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](../jenkins#readme) to set up your environment. +2. Follow all steps [here](../jenkins#valet-configure-lab) to configure Valet. + +## Perform an audit + +We will be performing an audit against a preconfigured Jenkins instance. Before running the command we need to collect some information: + + 1. Do we want to audit the entire Jenkins instance, or just a single folder? __In this example we will be auditing the entire Jenkins instance, but in the future if you wanted to configure a specific folder to be audited add the `-f ` flag to the audit command__ + 2. Where do we want to store the result? __./tmp/audit. This can be any valid path on the system. In the case of codespaces it is generally best to use `./tmp/SOME_DIRECTORY_HERE` so the files show in explorer__ + +### Steps + +1. Navigate to the codespace terminal. +2. Now, from root directory, run the following Valet audit command: + +``` +gh valet audit jenkins --output-dir tmp/audit +``` + +3. Valet will log the output files in green when the audit is successful + +### Example + +valet-audit-1 + +## View audit output + +The audit summary, logs, config files, jenkinsfiles, and transformed Actions Workflows should all be located within the `tmp/audit` folder. + +1. Under the `audit` 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, it should look like the image below: + +### Example + +valet-audit-2 + +## Review the pipelines + +### Pipelines + +The audit summary starts by giving a summary of the types of pipelines that were extracted from Jenkins. + +- It shows that there are a total of 7 pipelines extracted. + +- 42% pipelines were successful. This means that Valet knew how to map all the constructs of the Jenkins pipeline to a GitHub Actions equivalent. All of the build pluggins and triggers that are referenced were all successfully converted into a GitHub Actions equivalent. + +- 42% pipelines were partially successful. This means that Valet knew how to map all the constructs of the Jenkins pipeline but there may be a plugin that was referenced that Valet wasn't able to automatically map to a Github Actions equivalent. + +- 1% of these pipelines were unsupported. This means that the pipeline type is fundamentally unsupported by Valet. This is most likely a Jenkins scripted pipeline. + +- 0% of these fail altogether. If there were any pipelines that would fall under this category, that would mean that those pipelines were misconfigured or there was an issue with Valet. + +Under the `Job types` section, we can see that the `audit` command is able to support the conversion of project, freestyle (flow-defintion), and multibranch pipelines from Jenkins and convert them to a GitHub Actions workflow. Valet does not support converting [scripted pipelines](https://www.jenkins.io/doc/book/pipeline/syntax/#scripted-pipeline) (e.g. pure Groovy). + +#### Example + +valet-audit-3 + +### Build steps + +Under the `Build steps` section we can see a breakdown of the build steps that were used in these pipelines. + +- Supported: 12/16 discrete build steps are considered known by Valet. When Valet encounters a build step of this type, it knows exactly how to map that into a GitHub Actions equivalent. +- Unknown: 3/16 discrete build steps are considered unknown by Valet. When Valet enounters a build step of this type, it does not yet know to map this automatically to a GitHub Action equivalent. +- Unsupported: 1/16 discrete build steps are considered unsupported by Valet. This could mean one of three things: + 1. The way that plugin was configured for a given job is unsupported. + 2. The plugin itself is fundamentally not supported in GitHub Actions. + 3. It's supported by default in GitHub Actions. + +Under the `Actions` section we have the list of the Actions that were used in order to implement the transformation of all of these build steps. Valet is a planning tool that can help in facilitating the migration into GitHub Actions and this list of Actions is a great place to understand what dependencies you would be taking on third-party Actions after this migration. + +For example, if you are doing things like setting up the allow list of third-party Actions in a GitHub Enterprise server instance this list of Actions is a fantastic place to begin security reviews and audits of what third-party actions to depend on. + +#### Example + +valet-audit-4 + +### Trigger, Environment, Other + +Similar to `Build steps`, there are `Trigger`, `Environment`, and a catch all `Other` section that breakdown each of their uses accross the audited pipelines. + +### Example + +valet-audit-5 + +### Manual Tasks + +Under the Manual task section you will find a list of all the manual tasks that the pipelines would surface in a migration. Manual tasks are Valet's way of indicating tasks a user needs to do in order for a pipeline to be functional, such as adding `secrets`, or setting up a `self-hosted` runner. We will see how these manual tasks appear on a pull request when we do a migration in a lab later on. + +### Example + +valet-audit-5 + +### Files + +At the end of the Audit Summary page you will find a list of all of the files that were written to disk. Generally, for any given pipeline, you’ll find 2 or 3 associated files. In these files are the actual converted GitHub Actions workflows. + +In addition, you’ll see a file that shows the raw JSON data that we pull from Jenkins as well as any associated Jenkinsfiles for a given job. These files are really useful for engineering teams to help debug any issues and to understand what may have gone on in a transformation. + +#### Example + +valet-audit-6 + +### Next Lab + +[Dry run the migration of a Jenkins pipeline to GitHub Actions](valet-dry-run-lab.md) diff --git a/jenkins/valet-configure-lab.md b/jenkins/valet-configure-lab.md new file mode 100644 index 0000000..b9456c7 --- /dev/null +++ b/jenkins/valet-configure-lab.md @@ -0,0 +1,78 @@ +# Configure Valet to work with Jenkins + +In this lab, you will use the Valet `configure` command to set up the required information to communicate with the Jenkins and GitHub instances. The `configure` command can be used for all of the supported providers, in this lab we will be focusing on Jenkins. + +- [Prerequisites](#prerequisites) +- [Configuring Valet](#configuring-valet) +- [Verify Valet Works](#verify-valet-works) +- [Next Lab](#next-lab) + +## Prerequisites + +1. Followed [steps](../Jenkins#readme) to set up your codespace environment and start your Jenkins instanace. + +## Configuring Valet + +1. Login to the Jenkins instance to generate a personal access token: + 1. Click the `PORTS` tab in the codespace terminal window. + 2. In the `PORTS` tab find the row for port 8080. + 3. Hover over the address under the `Local Address` column, and click the globe to "open in browser". + 4. Login to the Jenkins server and generate a Jenkins API token. + - Click the `admin` button located within the top right menu. + - Click on the `configure` gear located on the left hand panel. + - Under the `API token` section, click `Add new Token`. + - Add a defaualt name to your token, then click `Generate`. + - Copy the token that was generated and record token for a later step. + +![configure-result](https://user-images.githubusercontent.com/19557880/184041667-d06cb7f2-a885-474e-b728-7567314aeaf3.png) + +2. Create a GitHub personal access token (PAT). + - 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 token somewhere safe and temporary. +3. Run Valet configure commands + - In the codespace terminal window click back to the `TERMINAL` tab. + - Within the terminal, ensure you are in the root dirrectory. + - Run `gh valet configure`. + - Use the down arrow key to highlight `Jenkins`, press the spacebar to select, then hit enter to accept. + - At the prompt enter your GitHub Username and press enter. + - At the GitHub Container Registry prompt enter the GitHub PAT generated in step 3 and press enter + - At the GitHub PAT prompt enter the GitHub PAT generated in step 3 and press enter. + - At the GitHub url prompt enter the GitHub instance url or hit enter to accept the default, if you are using github.com then the default is the right choice. + - At the Jenkins token prompt enter the Jenkins access token from step 2 and press enter. + - At the Jenkins url prompt enter `http://localhost:8080/` and press enter. + - At the Personal access token to fetch source code in GitHub prompt, if any of your Jenkins pipelines have source code in a GitHub repository enter the GitHub PAT that would have acess to these files. +4. If all went well you should see a similar output in your terminal: +![configure-result](https://user-images.githubusercontent.com/19557880/184041328-ce54ea22-b0cd-4c84-b02c-10ad7b09ad89.png) + +## Verify Valet Works + +To verify Valet works we are going to run a `update` and `dry-run` command. We will go further into details about the `dry-run` command in a later lab, but for now we want to get the latest version of Valet and confirm that Valet can perform a dry-run with no errors. + +1. In the codespace terminal update Valet by running `gh valet update` +2. In the terminal you should see a confirmation that it logged into the GitHub Container Registry and pulled the latest version. + + ``` + Login Succeeded + latest: Pulling from valet-customers/valet-cli + Digest: sha256:a7d00dee8a37e25da59daeed44b1543f476b00fa2c41c47f48deeaf34a215bbb + Status: Image is up to date for ghcr.io/valet-customers/valet-cli:latest + ghcr.io/valet-customers/valet-cli:latest + ``` + + 3. Next, lets run the dry-run command in the codespaces terminal, to verify we can talk to Jenkins + + ``` + gh valet dry-run jenkins --source-url https://localhost:8080/job/test_pipeline/ --output-dir ./tmp/dry-run-lab + ``` + + 4. In the terminal you should see the command was successful, if not it is a good time to practice the configure command again and make sure the access tokens values are correct and were generated with the correct permissions. + ![configure-dry-run](https://user-images.githubusercontent.com/19557880/184255620-8e9b120e-5de0-41df-9cb6-c52028de3b0f.png) + +### Next Lab + +TODO diff --git a/readme.md b/readme.md index 690dc5c..cefd92e 100644 --- a/readme.md +++ b/readme.md @@ -1,13 +1,16 @@ -# Welcome to Valet labs! +# 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). +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) and [Jenkins](jenkins). 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: +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 @@ -17,6 +20,6 @@ These Valet labs let you test-drive Valet by bootstrapping the environment of yo ![createtemplate](https://user-images.githubusercontent.com/26442605/174847176-0e515fd3-8107-43e0-af33-70b1ece36d3b.png) ## Environments to bootstrap + - [Azure DevOps](azure_devops) - [Jenkins](jenkins) -