Merge remote-tracking branch 'origin/main' into feature/azdo-labs
This commit is contained in:
+4
-1
@@ -350,4 +350,7 @@ MigrationBackup/
|
||||
.ionide/
|
||||
|
||||
# valet files
|
||||
valet/.env*local
|
||||
.env*local
|
||||
credentials_file.yaml
|
||||
|
||||
.vscode
|
||||
@@ -0,0 +1,72 @@
|
||||
# Configure credentials for Valet
|
||||
|
||||
In this lab, you will use the `configure` CLI command to set the required credentials and information for Valet to use when working with GitLab and GitHub.
|
||||
|
||||
You will need to complete all of the setup instructions [here](./readme.md#configure-your-codespace) prior to performing this lab.
|
||||
|
||||
## Configuring credentials
|
||||
|
||||
1. Run the setup script in the codespace's terminal to ensure the GitLab server is ready:
|
||||
```bash
|
||||
./gitlab/bootstrap/setup.sh
|
||||
```
|
||||
|
||||
2. Open the GitLab server in a new browser tab:
|
||||
- Click the `PORTS` tab in the codespace terminal window.
|
||||
- In the `PORTS` tab find the row for port 80.
|
||||
- Hover over the address under the `Local Address` column and click the globe to "open in browser".
|
||||
|
||||
3. Create a GitLab personal access token:
|
||||
- Authenticate with the GitLab server using the following credentials:
|
||||
- Username: `root`
|
||||
- Password: `valet-labs!`
|
||||
- Follow the GitLab [instructions](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-personal-access-token) to generate a personal access token.
|
||||
- Ensure the token has the `read_api` scope.
|
||||
- Copy the generated token and save in a safe location.
|
||||
|
||||
4. Create a GitHub Personal Access Token (PAT):
|
||||
- Open github.com in a new browser tab.
|
||||
- Click your profile photo in the top right of the UI and click `Settings`.
|
||||
- Click on `Developer Settings` in the left hand panel.
|
||||
- Click `Personal Access Tokens` and then `Legacy tokens` (if present).
|
||||
- Click `Generate new token` and then `Legacy tokens`. You may be required to authenticate with GitHub during this step.
|
||||
- Select the following scopes: `read:packages` and `workflow`.
|
||||
- Click `Generate token`.
|
||||
- Copy the generated PAT and save in a safe location.
|
||||
|
||||
4. Run the `configure` CLI command:
|
||||
- Select the `TERMINAL` tab from within the codespace terminal window.
|
||||
- Run the following command: `gh valet configure`.
|
||||
- Using the down arrow key to highlight `GitLab CI`, press the spacebar to select, and then hit enter to continue.
|
||||
- At the prompt enter your GitHub Username and press enter.
|
||||
- At the GitHub Container Registry prompt enter the GitHub PAT generated in step 4 and press enter.
|
||||
- At the GitHub PAT prompt enter the GitHub PAT generated in step 4 and press enter.
|
||||
- At the GitHub url prompt enter the GitHub instance url or hit enter to accept the default value (`https://github.com`).
|
||||
- At the GitLab CI token prompt enter the GitLab CI access token from step 3 and press enter.
|
||||
- At the GitLab CI url prompt enter `http://localhost` and press enter.
|
||||
|
||||

|
||||
|
||||
## Verify your environment
|
||||
|
||||
To verify our environment is configured correctly, we are going to run the `update` CLI command. The `update` CLI command will download the latest version of Valet to your codespace.
|
||||
|
||||
1. In the codespace terminal run the following command:
|
||||
|
||||
```bash
|
||||
gh valet update
|
||||
```
|
||||
|
||||
2. You should see a confirmation that you were logged into the GitHub Container Registry and Valet was updated to the latest version.
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
### Next lab
|
||||
|
||||
[Perform an audit of a GitLab server](./2-audit.md)
|
||||
@@ -0,0 +1,182 @@
|
||||
# Perform an audit of a GitLab server
|
||||
|
||||
In this lab, you will use the `audit` command to get a high-level view of all pipelines in a GitLab server.
|
||||
|
||||
The `audit` command operates by fetching all of the pipelines defined in a GitLab server, converting each to their equivalent GitHub Actions workflow, and writing a report that summarizes how complete and complex of a migration is possible with Valet.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Followed the steps [here](./readme.md#configure-your-codespace) to set up your Codespace environment and start a GitLab server.
|
||||
2. Completed the [configure lab](./1-configure.md#configuring-credentials).
|
||||
|
||||
## Perform an audit
|
||||
|
||||
We will be performing an audit against your preconfigured GitLab server. We will need to answer the following questions before running this command:
|
||||
|
||||
1. What namespace (e.g. group) do we want to audit?
|
||||
- __valet__. In this example we will be auditing the `valet` group. In the future, you could add additional groups and subgroups to the audit command.
|
||||
|
||||
2. Where do we want to store the result?
|
||||
- __./tmp/audit__. This can be any path within the working directory that Valet commands are executed from.
|
||||
|
||||
### Steps
|
||||
|
||||
1. Navigate to the codespace terminal.
|
||||
2. Run the following command from the root directory:
|
||||
|
||||
```bash
|
||||
gh valet audit gitlab --output-dir tmp/audit --namespace valet
|
||||
```
|
||||
|
||||
3. The command will list all the files written to disk in green when the command succeeds.
|
||||
|
||||
## Inspect the output files
|
||||
|
||||
1. Find the `audit_summary.md` file in the file explorer.
|
||||
2. Right-click the `audit_summary.md` file and select `Open Preview`.
|
||||
3. This file contains details that summarizes what percentage of your pipelines were converted automatically.
|
||||
|
||||
### Review audit summary
|
||||
|
||||
#### Pipelines
|
||||
|
||||
The pipeline summary section contains high level statistics regarding the conversion rate done by Valet:
|
||||
|
||||
```md
|
||||
## Pipelines
|
||||
|
||||
Total: **11**
|
||||
|
||||
- Successful: **10 (90%)**
|
||||
- Partially successful: **0 (0%)**
|
||||
- Unsupported: **1 (9%)**
|
||||
- Failed: **0 (0%)**
|
||||
|
||||
### Job types
|
||||
|
||||
Supported: **10 (90%)**
|
||||
|
||||
- YAML: **10**
|
||||
|
||||
Unsupported: **1 (9%)**
|
||||
|
||||
- Auto DevOps: **1**
|
||||
```
|
||||
|
||||
Here are some key terms in the “Pipelines” section in the above example:
|
||||
|
||||
- __Successful__ pipelines had 100% of the pipeline constructs and individual items converted automatically to their GitHub Actions equivalent.
|
||||
- __Partially successful__ pipelines had all of the pipeline constructs converted, however, there were some "Auto DevOps" pipelines.
|
||||
- __Failed pipelines__ encountered a fatal error when being converted. This can occur for one of three reasons:
|
||||
- The pipeline was misconfigured and not valid in GitLab.
|
||||
- Valet encountered an internal error when converting it.
|
||||
- There was an unsuccessful network response, often due to invalid credentials, that caused the pipeline to be inaccessible.
|
||||
|
||||
The "Job types" section will summarize which types of pipelines are being used and which are supported or unsupported by Valet.
|
||||
|
||||
#### Build steps
|
||||
|
||||
The build steps summary section presents an overview of the individual build steps that are used across all pipelines and how many were automatically converted by Valet.
|
||||
|
||||
```md
|
||||
### Build steps
|
||||
|
||||
Total: **134**
|
||||
|
||||
Known: **133 (99%)**
|
||||
|
||||
- script: **62**
|
||||
- checkout: **35**
|
||||
- before_script: **19**
|
||||
- artifacts: **5**
|
||||
- after_script: **4**
|
||||
- dependencies: **4**
|
||||
- cache: **3**
|
||||
- pages: **1**
|
||||
|
||||
Unsupported: **1 (0%)**
|
||||
|
||||
- artifacts.terraform: **1**
|
||||
|
||||
Actions: **135**
|
||||
|
||||
- run: **85**
|
||||
- actions/checkout@v2: **35**
|
||||
- actions/upload-artifact@v2: **5**
|
||||
- actions/download-artifact@v2: **4**
|
||||
- actions/cache@v2: **3**
|
||||
- ./.github/workflows/a-.gitlab-ci.yml: **1**
|
||||
- ./.github/workflows/b-.gitlab-ci.yml: **1**
|
||||
- JamesIves/[email protected]: **1**
|
||||
```
|
||||
|
||||
Here are some key terms in the "Build steps" section in the above example:
|
||||
|
||||
- A __known__ build step is a step that was automatically converted to an equivalent action.
|
||||
- An __unknown__ build step is a step that was not automatically converted to an equivalent action.
|
||||
- An __unsupported__ build step is a step that is either:
|
||||
- A step that is fundamentally not supported by GitHub Actions.
|
||||
- A step that is configured in a way that is incompatible with GitHub Actions.
|
||||
- An __action__ is a list of the actions that were used in the converted workflows. This is important for the following scenarios:
|
||||
- Gathering the list of actions to sync to your appliance if you use GitHub Enterprise Server.
|
||||
- Defining an organization-level allowlist of actions that can be used. This list of actions is a comprehensive list of which actions their security and/or compliance teams will need to review.
|
||||
|
||||
There is an equivalent breakdown of build triggers, environment variables, and other uncategorized items displayed in the audit summary file.
|
||||
|
||||
#### Manual Tasks
|
||||
|
||||
The manual tasks summary section presents an overview of the manual tasks that you will need to perform that Valet is not able to complete automatically.
|
||||
|
||||
```md
|
||||
### Manual tasks
|
||||
|
||||
Total: **1**
|
||||
|
||||
Secrets: **1**
|
||||
|
||||
- `${{ secrets.PASSWORD }}`: **1**
|
||||
```
|
||||
|
||||
Here are some key terms in the “Manual tasks” section in the above example:
|
||||
|
||||
- A __secret__ refers to a repository or organization level secret that is used by the converted pipelines. These secrets will need to be created manually in Actions in order for these pipelines to function properly.
|
||||
- A __self-hosted runner__ refers to a label of a runner that is referenced by a converted pipeline that is not a GitHub-hosted runner. You will need to manually define these runners in order for these pipelines to function properly.
|
||||
|
||||
#### Files
|
||||
|
||||
The final section of the audit report provides a manifest of all of the files that are written to disk during the audit. These files include:
|
||||
|
||||
```md
|
||||
### Successful
|
||||
|
||||
#### valet/included-files-example
|
||||
|
||||
- [valet/included-files-example.yml](valet/included-files-example.yml)
|
||||
- [valet/included-files-example.config.json](valet/included-files-example.config.json)
|
||||
- [valet/included-files-example.source.yml](valet/included-files-example.source.yml)
|
||||
|
||||
#### valet/terraform-example
|
||||
|
||||
- [valet/terraform-example.yml](valet/terraform-example.yml)
|
||||
- [valet/terraform-example.config.json](valet/terraform-example.config.json)
|
||||
- [valet/terraform-example.source.yml](valet/terraform-example.source.yml)
|
||||
|
||||
#### valet/child-parent-example
|
||||
|
||||
- [valet/child-parent-example.yml](valet/child-parent-example.yml)
|
||||
- [.github/workflows/a-.gitlab-ci.yml](.github/workflows/a-.gitlab-ci.yml)
|
||||
- [.github/workflows/b-.gitlab-ci.yml](.github/workflows/b-.gitlab-ci.yml)
|
||||
- [valet/child-parent-example.config.json](valet/child-parent-example.config.json)
|
||||
- [valet/child-parent-example.source.yml](valet/child-parent-example.source.yml)
|
||||
```
|
||||
|
||||
Each pipeline will have a variety of files written that include:
|
||||
|
||||
- The original pipeline as it was defined in GitLab.
|
||||
- Any network responses used to convert a pipeline.
|
||||
- The converted workflow.
|
||||
- Stack traces that can used to troubleshoot a failed pipeline conversion
|
||||
|
||||
### Next lab
|
||||
|
||||
[Perform a dry-run of a GitLab pipeline](3-dry-run.md)
|
||||
@@ -0,0 +1,254 @@
|
||||
# Perform a dry-run of a GitLab pipeline
|
||||
|
||||
In this lab you will use the `dry-run` command to convert a GitLab pipeline to its equivalent GitHub Actions workflow.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Followed the steps [here](./readme.md#configure-your-codespace) to set up your Codespace environment and start a GitLab server.
|
||||
2. Completed the [configure lab](./1-configure-lab.md#configuring-credentials).
|
||||
3. Completed the [audit lab](./2-audit.md).
|
||||
|
||||
## Perform a dry run
|
||||
|
||||
We will be performing a dry-run against a pipeline in your preconfigured GitLab server. We will need to answer the following questions before running this command:
|
||||
|
||||
1. What is the project we want to convert?
|
||||
- __basic-pipeline-example__
|
||||
|
||||
2. What is the namespace for that project?
|
||||
- __Valet__
|
||||
|
||||
3. Where do we want to store the result?
|
||||
- __./tmp/dry-run-lab__. This can be any path within the working directory that Valet commands are executed from.
|
||||
|
||||
### Steps
|
||||
|
||||
1. Navigate to the codespace terminal
|
||||
2. Run the following command from the root directory:
|
||||
|
||||
```bash
|
||||
gh valet dry-run gitlab --output-dir ./tmp/dry-run-lab --namespace valet --project basic-pipeline-example
|
||||
```
|
||||
|
||||
3. The command will list all the files written to disk when the command succeeds.
|
||||
|
||||

|
||||
|
||||
4. View the converted workflow:
|
||||
- Find `./tmp/dry-run/valet` in the file explorer pane in codespaces.
|
||||
- Click `basic-pipeline-example.yml` to open.
|
||||
|
||||
## Inspect the output files
|
||||
|
||||
The files generated from the `dry-run` command represent the equivalent Actions workflow for the given GitLab pipeline. The GitLab pipeline and converted workflow can be seen below:
|
||||
|
||||
<details>
|
||||
<summary><em>GitLab pipeline 👇</em></summary>
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
image: alpine
|
||||
|
||||
build_a:
|
||||
stage: build
|
||||
script:
|
||||
- echo "This job builds something."
|
||||
- sleep 100
|
||||
|
||||
build_b:
|
||||
stage: build
|
||||
script:
|
||||
- echo "This job builds something else."
|
||||
- sleep 70
|
||||
|
||||
test_a:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job tests something. It will only run when all jobs in the"
|
||||
- echo "build stage are complete."
|
||||
|
||||
test_b:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job tests something else. It will only run when all jobs in the"
|
||||
- echo "build stage are complete too. It will start at about the same time as test_a."
|
||||
- sleep 300
|
||||
|
||||
deploy_a:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "This job deploys something. It will only run when all jobs in the"
|
||||
- echo "test stage complete."
|
||||
- sleep 600
|
||||
|
||||
deploy_b:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "This job deploys something else. It will only run when all jobs in the"
|
||||
- echo "test stage complete. It will start at about the same time as deploy_a."
|
||||
- sleep 400
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><em>Converted workflow 👇</em></summary>
|
||||
|
||||
```yaml
|
||||
name: valet/basic-pipeline-example
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
concurrency:
|
||||
group: "${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build_a:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
lfs: true
|
||||
- run: echo "This job builds something."
|
||||
- run: sleep 100
|
||||
build_b:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
lfs: true
|
||||
- run: echo "This job builds something else."
|
||||
- run: sleep 70
|
||||
test_a:
|
||||
needs:
|
||||
- build_a
|
||||
- build_b
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
lfs: true
|
||||
- run: echo "This job tests something. It will only run when all jobs in the"
|
||||
- run: echo "build stage are complete."
|
||||
test_b:
|
||||
needs:
|
||||
- build_a
|
||||
- build_b
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
lfs: true
|
||||
- run: echo "This job tests something else. It will only run when all jobs in the"
|
||||
- run: echo "build stage are complete too. It will start at about the same time as test_a."
|
||||
- run: sleep 300
|
||||
deploy_a:
|
||||
needs:
|
||||
- test_a
|
||||
- test_b
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
lfs: true
|
||||
- run: echo "This job deploys something. It will only run when all jobs in the"
|
||||
- run: echo "test stage complete."
|
||||
- run: sleep 600
|
||||
deploy_b:
|
||||
needs:
|
||||
- test_a
|
||||
- test_b
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
lfs: true
|
||||
- run: echo "This job deploys something else. It will only run when all jobs in the"
|
||||
- run: echo "test stage complete. It will start at about the same time as deploy_a."
|
||||
- run: sleep 400
|
||||
```
|
||||
</details>
|
||||
|
||||
Despite these 2 pipelines using different syntax they will function equivantly.
|
||||
|
||||
## Perform a dry-run of a pipeline using `include`'d files
|
||||
|
||||
The previous example demonstrated a basic pipeline that mapped exactly to concepts in GitHub Actions. In this section, we will perform a dry-run of the `included-files-example` pipeline that uses the `include` statement in GitLab:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- local: /config/build.gitlab-ci.yml
|
||||
- local: /config/test.gitlab-ci.yml
|
||||
```
|
||||
|
||||
The output of the `dry-run` command can be seen below:
|
||||
|
||||
```yaml
|
||||
name: valet/included-files-example
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
concurrency:
|
||||
group: "${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 50
|
||||
lfs: true
|
||||
- run: echo "[BEFORE_SCRIPT] this is from test.gitlab-ci.yml"
|
||||
- run: echo "this is from a local file"
|
||||
test:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 50
|
||||
lfs: true
|
||||
- run: echo "[BEFORE_SCRIPT] this is from test.gitlab-ci.yml"
|
||||
- run: echo "this is from a local file"
|
||||
```
|
||||
|
||||
It's important to note that Valet converted this into a single workflow without templates. This is because of fundamental differences in how GitLab templates and GitHub Actions templates (i.e. Reusable Workflows and Composite Actions) function in regards to job ordering. Unfortunately, elements of reusability will be sacrificed in order for the converted pipelines to function the same. It is likely that the output of Valet could be refactored to use [reusable workflow](https://docs.github.com/en/actions/using-workflows/reusing-workflows) at a later date.
|
||||
|
||||
As an added challenge, try constructing and running the `dry-run` command yourself. Hint, you should just have to change the project name.
|
||||
|
||||
## Next lab
|
||||
|
||||
[Use custom transformers to customize Valet's behavior](./4-custom-transformers.md)
|
||||
@@ -0,0 +1,166 @@
|
||||
# Using custom transformers to customize Valet's behavior
|
||||
|
||||
In this lab we will build upon the `dry-run` command to override Valet's default behavior and customize the converted workflow using "custom transformers". Custom transformers can be used to:
|
||||
|
||||
1. Convert items that are not automatically converted.
|
||||
2. Convert items that were automatically converted using different actions.
|
||||
3. Convert environment variable values differently.
|
||||
4. Convert references to runners to use a different runner name in Actions.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Followed the steps [here](./readme.md#configure-your-codespace) to set up your Codespace environment and start you GitLab server.
|
||||
2. Completed the [configure lab](./1-configure-lab.md#configuring-credentials).
|
||||
3. Completed the [dry-run lab](./3-dry-run.md).
|
||||
|
||||
## Perform a dry-run
|
||||
|
||||
We will be performing a `dry-run` command to inspect the workflow that is converted by default. Run the following command within the codespace terminal:
|
||||
|
||||
```bash
|
||||
gh valet dry-run gitlab --output-dir tmp --namespace valet --project terraform-example
|
||||
```
|
||||
|
||||
The converted workflow that is generated by the above command can be seen below:
|
||||
|
||||
<details>
|
||||
<summary><em>Converted workflow 👇</em></summary>
|
||||
|
||||
```yaml
|
||||
name: valet/custom-transformer
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
concurrency:
|
||||
group: "${{ github.ref }}"
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
plan:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
PLAN: plan.cache
|
||||
PLAN_JSON: plan.json
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20
|
||||
lfs: true
|
||||
- run: terraform plan -out=$PLAN
|
||||
- run: terraform show --json $PLAN | convert_report > $PLAN_JSON
|
||||
# # 'artifacts.terraform' was not transformed because there is no suitable equivalent in GitHub Actions
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
_Note_: You can refer to the previous [lab](./3-dry-run.md) to learn about the fundamentals of the `dry-run` command.
|
||||
|
||||
## Custom transformers for an unknown step
|
||||
|
||||
The converted workflow above contains an `artifacts.terraform` step was not automatically converted. We will need to answer the following questions before writing a custom transformer:
|
||||
|
||||
1. What is the "identifier" of the step to customize?
|
||||
- __artifacts.terraform__
|
||||
|
||||
2. What is the desired Actions syntax to use instead?
|
||||
- After some research, we have determined that the following bash script will provide similar functionality:
|
||||
|
||||
```yaml
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: VALUE_FROM_GITLAB
|
||||
```
|
||||
|
||||
Now we can begin to write the custom transformer. Customer transformers use a DSL built on top of Ruby and should be defined in a file with the `.rb` file extension. You can create this file by running the following command in your codespace terminal:
|
||||
|
||||
```bash
|
||||
code transformers.rb
|
||||
```
|
||||
|
||||
Next, we will define a `transform` method for the `artifacts.terraform` identifier by adding the following code to `transformers.rb`:
|
||||
|
||||
```ruby
|
||||
transform "artifacts.terraform" do |item|
|
||||
{
|
||||
uses: "actions/upload-artifact@v2",
|
||||
with: {
|
||||
path: item
|
||||
}
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
This method can use any valid ruby syntax and should return a `Hash` that represents the YAML that should be generated for a given step. Valet will use this method to convert a step with the provided identifier and will use the `item` parameter for the original values configured in GitLab.
|
||||
|
||||
Now, we can perform another `dry-run` command and use the `--custom-transformers` CLI option to provide this custom transformer. Run the following command within your codespace terminal:
|
||||
|
||||
```bash
|
||||
gh valet dry-run gitlab --output-dir tmp --namespace valet --project terraform-example --custom-transformers transformers.rb
|
||||
```
|
||||
|
||||
The converted workflow that is generated by the above command will now use the custom logic for the `artifacts.terraform` step.
|
||||
|
||||
```diff
|
||||
- # # 'artifacts.terraform' was not transformed because there is no suitable equivalent in GitHub Actions
|
||||
+ uses: actions/upload-artifact@v2
|
||||
+ with:
|
||||
+ path: "$PLAN_JSON"
|
||||
```
|
||||
|
||||
_Note_: If you were unsure what the data structure of `item` was then you could use the following code in the custom transformer to print `item` to the console:
|
||||
|
||||
```ruby
|
||||
transform "artifacts.terraform" do |item|
|
||||
puts item
|
||||
end
|
||||
```
|
||||
|
||||
## Custom transformers for environment variables
|
||||
|
||||
We can also use custom transformers to edit the values of environment variables in converted workflows. In our example, we will be updating the `PLAN_JSON` environment variable to be `custom_plan.json` instead of `plan.json`.
|
||||
|
||||
To do this, add the following code to the `transformers.rb` file.
|
||||
|
||||
```ruby
|
||||
env "PLAN_JSON", "custom_plan.json"
|
||||
```
|
||||
|
||||
In this example, the first parameter to the `env` method is the environment variable name and the second is the updated value.
|
||||
|
||||
Now, we can perform another `dry-run` command with the `--custom-transformers` CLI option. When you open the converted workflow the `PLAN_JSON` environment variable will be set to `custom_plan.json`:
|
||||
|
||||
```diff
|
||||
env:
|
||||
PLAN: plan.cache
|
||||
- PLAN_JSON: plan.json
|
||||
+ PLAN_JSON: custom_plan.json
|
||||
```
|
||||
|
||||
At this point of the lab the file contents of `transformers.rb` should match this:
|
||||
|
||||
<details>
|
||||
<summary><em>Custom transformers 👇</em></summary>
|
||||
|
||||
```ruby
|
||||
env "PLAN_JSON", "custom_plan.json"
|
||||
|
||||
transform "artifacts.terraform" do |item|
|
||||
{
|
||||
uses: "actions/upload-artifact@v2",
|
||||
with: {
|
||||
path: item
|
||||
}
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Thats it! Congratulations you have overridden Valet's default behavior by customizing the conversion of:
|
||||
|
||||
- Unknown steps
|
||||
- Environment variables
|
||||
|
||||
## Next lab
|
||||
|
||||
[Perform a production migration of a GitLab pipeline](5-migrate.md)
|
||||
@@ -0,0 +1,53 @@
|
||||
# Perform a production migration of a GitLab pipeline
|
||||
|
||||
In this lab, you will use the `migrate` command to convert a GitLab pipeline and open a pull request with the equivalent Actions workflow.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Followed the steps [here](./readme.md#configure-your-codespace) to set up your Codespace environment and start a GitLab server.
|
||||
2. Completed the [configure lab](./1-configure-lab.md#configuring-credentials).
|
||||
3. Completed the [dry-run lab](./3-dry-run.md).
|
||||
4. Completed the [custom transformers lab](./4-custom-transformers.md).
|
||||
|
||||
## Performing a migration
|
||||
|
||||
We need to answer the following questions before running a `migrate` command:
|
||||
|
||||
1. What is the project we want to migrate?
|
||||
- __rails-example__
|
||||
2. What is the namespace for that project?
|
||||
- __Valet__
|
||||
3. Where do we want to store the logs?
|
||||
- __./tmp/migrate__
|
||||
4. What is the URL for the GitHub repository to add the workflow to?
|
||||
- __this repository__. The URL should should follow the pattern <https://github.com/:owner/:repo> with `:owner` and `:repo` replaced with your values.
|
||||
|
||||
### Steps
|
||||
|
||||
1. Run the following `migrate` command in the codespace terminal:
|
||||
|
||||
```bash
|
||||
gh valet migrate gitlab --target-url https://github.com/:owner/:repo --output-dir ./tmp/migrate --namespace valet --project rails-example
|
||||
```
|
||||
|
||||
2. The command will write the URL to the pull request that was created when the command succeeds.
|
||||
|
||||

|
||||
|
||||
3. Open the generated pull request in a new browser tab.
|
||||
|
||||
### Inspect the pull request
|
||||
|
||||
The first thing we should notice about the PR is that there is a list of manual steps for us to complete.
|
||||
|
||||
Next, you can inspect the "Files changed" in this PR and see the converted workflow that is being added. Any additional changes or code reviews that were needed should be done in this PR.
|
||||
|
||||
Finally, you can merge the PR once your review has completed. We can then view the workflow running by selecting the "Actions" menu in the top navigation bar in GitHub.
|
||||
|
||||

|
||||
|
||||
At this point, the migration has completed and you have successfully migrated a GitLab pipeline to Actions!
|
||||
|
||||
### Next Lab
|
||||
|
||||
[Forecast potential build runner usage](6-forecast.md)
|
||||
@@ -0,0 +1,102 @@
|
||||
# Forecast potential build runner usage
|
||||
|
||||
In this lab you will use the `forecast` command to forecast potential GitHub Actions usage by computing metrics from completed pipeline runs in your GitLab server.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Followed the steps [here](./readme.md#configure-your-codespace) to set up your Codespace environment and start a GitLab server.
|
||||
2. Completed the [configure lab](./1-configure-lab.md#configuring-credentials).
|
||||
|
||||
## Perform a forecast
|
||||
|
||||
We will need to answer the following questions before running the `forecast` command:
|
||||
|
||||
1. What namespace do we want to run the forecast for?
|
||||
- **valet**
|
||||
2. What is the date we want to start forecasting from?
|
||||
- **2022-08-02**. This date is needed as it is prior to when the data was seeded in GitLab for these labs. This value defaults to the date one week ago, however, you should use a start date that will show a representative view of typical usage.
|
||||
3. Where do we want to store the results?
|
||||
- **./tmp/forecast_reports**
|
||||
|
||||
### Steps
|
||||
|
||||
1. Navigate to the codespace terminal
|
||||
2. Run the following command from the root directory:
|
||||
|
||||
```bash
|
||||
gh valet forecast gitlab --output-dir ./tmp/forecast_reports --namespace valet --start-date 2022-08-02
|
||||
```
|
||||
|
||||
3. The command will list all the files written to disk when the command succeeds.
|
||||
|
||||

|
||||
|
||||
## Review the forecast report
|
||||
|
||||
The forecast report, logs, and completed job data will be located within the `tmp/forecast_reports` folder.
|
||||
|
||||
1. Find the `forecast_report.md` file in the file explorer.
|
||||
2. Right-click the `forecast_report.md` file and select `Open Preview`.
|
||||
3. This file contains metrics used to forecast potential GitHub Actions usage.
|
||||
|
||||
### Total
|
||||
|
||||
The "Total" section of the forecast report contains high level statistics related to all the jobs completed after the `--start-date` CLI option:
|
||||
|
||||
```md
|
||||
- Job count: **57**
|
||||
- Pipeline count: **15**
|
||||
|
||||
- Execution time
|
||||
|
||||
- Total: **135 minutes**
|
||||
- Median: **0 minutes**
|
||||
- P90: **7 minutes**
|
||||
- Min: **0 minutes**
|
||||
- Max: **10 minutes**
|
||||
|
||||
- Queue time
|
||||
|
||||
- Median: **0 minutes**
|
||||
- P90: **5 minutes**
|
||||
- Min: **0 minutes**
|
||||
- Max: **42 minutes**
|
||||
|
||||
- Concurrent jobs
|
||||
|
||||
- Median: **0**
|
||||
- P90: **0**
|
||||
- Min: **0**
|
||||
- Max: **9**
|
||||
```
|
||||
|
||||
Here are some key terms of items defined in the forecast report:
|
||||
|
||||
- The `job count` is the total number of completed jobs.
|
||||
- The `pipeline count` is the number of unique pipelines used.
|
||||
- `Execution time` describes the amount of time a runner spent on a job. This metric can be used to help plan for the cost of GitHub hosted runners.
|
||||
- This metric is correlated to how much you should expect to spend in GitHub Actions. This will vary depending on the hardware used for these minutes and the [Actions pricing calculator](https://github.com/pricing/calculator) should be used to estimate a dollar amount.
|
||||
- `Queue time` metrics describe the amount of time a job spent waiting for a runner to be available to execute it.
|
||||
- `Concurrent jobs` metrics describe the amount of jobs running at any given time. This metric can be used to define the number of runners a customer should configure.
|
||||
|
||||
Additionally, these metrics are defined for each queue of runners defined in GitLab. This is especially useful if there are a mix of hosted/self-hosted runners or high/low spec machines to see metrics specific to different types of runners.
|
||||
|
||||
## Forecasting multiple providers
|
||||
|
||||
We can examine the available options for the `forecast` command by running `gh valet forecast --help`. When you do this you will see the `--source-file-path` option:
|
||||
|
||||

|
||||
|
||||
The `--source-file-path` CLI option can be used to combine data from multiple reports into a single report. This becomes useful if you use multiple CI/CD providers and wanted to get a holistic view of the runner usage. This works by using the `.json` files generated by `forecast` commands as space-delimited values for the `--source-file-path` CLI option. Optionally, this value could be a glob pattern to dynamically specify the list of files (e.g. `**/*.json`).
|
||||
|
||||
Run the following command from within the codespace terminal:
|
||||
|
||||
```bash
|
||||
gh valet forecast --source-file-path tmp/**/jobs/*.json -o tmp/combined-forecast
|
||||
```
|
||||
|
||||
You can now inspect the output of the command to see a forecast report using all of the files matching the `tmp/**/jobs/*.json` pattern.
|
||||
|
||||
## Next steps
|
||||
|
||||
This concludes all labs for migrating GitLab pipelines to Actions with Valet!
|
||||
Binary file not shown.
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
container_name="gitlab"
|
||||
tar_file_path="$CODESPACE_VSCODE_FOLDER/gitlab/bootstrap/gitlab.tar.gz"
|
||||
|
||||
if [ ! -d /srv/gitlab ]; then
|
||||
echo -e "Seeding GitLab data \U1F331"
|
||||
if [ ! -f $tar_file_path ]; then
|
||||
echo -e "GitLab data file not found at $tar_file_path.\nPlease verify this file has not been removed\nExiting..."
|
||||
return
|
||||
fi
|
||||
sudo tar -xzf $tar_file_path -C /srv
|
||||
fi
|
||||
|
||||
echo -e "Checking for GitLab \U1F575"
|
||||
|
||||
if [ "$(docker ps -a | grep $container_name)" ]; then
|
||||
echo -e "GitLab is running \U1F603"
|
||||
docker start $container_name
|
||||
else
|
||||
echo -e "Starting new GitLab container \U1F4E0"
|
||||
docker run --detach \
|
||||
--hostname 172.17.0.2 \
|
||||
--publish 80:80 \
|
||||
--name gitlab \
|
||||
--restart always \
|
||||
--volume /srv/gitlab/config:/etc/gitlab \
|
||||
--volume /srv/gitlab/logs:/var/log/gitlab \
|
||||
--volume /srv/gitlab/data:/var/opt/gitlab \
|
||||
--shm-size 256m \
|
||||
gitlab/gitlab-ee:latest
|
||||
|
||||
# updates file permissions to avoid git and server errors
|
||||
docker exec -it gitlab update-permissions &> /dev/null
|
||||
fi
|
||||
|
||||
# allow valet to talk to GitLab 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 "Waiting for GitLab to be ready. This might take a while \U23F0"
|
||||
until $(curl --output /dev/null --silent --head --fail http://localhost); do
|
||||
printf '.'
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo -e '\nGitLab is up and running! \U1F680'
|
||||
@@ -0,0 +1,93 @@
|
||||
# GitLab to Actions migrations powered by Valet
|
||||
|
||||
The instructions below will guide you through configuring a GitHub Codespace environment that will be used in subsequent labs that demonstrate how to use Valet to migrate GitLab pipelines to GitHub Actions.
|
||||
|
||||
These steps **must** be completed prior to starting other labs.
|
||||
|
||||
## Create your own repository for these labs
|
||||
|
||||
1. Ensure that you have created a repository using the [valet-customers/labs](https://github.com/valet-customers/labs) as a template.
|
||||
|
||||
## Configure your Codespace
|
||||
|
||||
1. Start the codespace
|
||||
|
||||
- Click the `Code` button down arrow above the repository on the repository's landing page.
|
||||
- Click the `Codespaces` tab.
|
||||
- Click `Create codespaces on main` to create the codespace.
|
||||
- After the Codespace has initialized there will be a terminal present.
|
||||
|
||||
2. Verify the Valet CLI is installed and working. More information on the Valet extension for the official GitHub CLI can be found [here](https://github.com/github/gh-valet).
|
||||
|
||||
- Run the following command in the codespace's terminal:
|
||||
|
||||
```bash
|
||||
gh valet version
|
||||
```
|
||||
|
||||
- Verify the output is similar to below.
|
||||
|
||||
```bash
|
||||
gh version 2.14.3 (2022-07-26)
|
||||
gh valet github/gh-valet v0.1.12
|
||||
valet-cli unknown
|
||||
```
|
||||
|
||||
- If `gh valet version` did not produce similar output then please follow the troubleshooting [guide](#troubleshoot-the-valet-cli).
|
||||
|
||||
## Bootstrap a GitLab server
|
||||
|
||||
1. Execute the GitLab setup script that will start a container with GitLab running inside of it. The script should be executed when starting a new Codespace or restarting an existing one.
|
||||
|
||||
- Run the following command from the codespace's terminal:
|
||||
|
||||
```bash
|
||||
./gitlab/bootstrap/setup.sh
|
||||
```
|
||||
|
||||
- After some time, a pop-up box should appear with a link to the URL for your GitLab server.
|
||||
- You can also access the URL by going to the `Ports` tab in your terminal. Right click on the URL listed under the `Local Address` and click the `Open in Browser` tab.
|
||||
|
||||
2. Open the GitLab server in your browser and use the following credentials to authenticate:
|
||||
|
||||
- Username: `root`
|
||||
- Password: `valet-labs!`
|
||||
|
||||
- Once authenticated, you should see a GitLab server with a few predefined pipelines in the `valet` group.
|
||||
|
||||
## Labs for GitLab
|
||||
|
||||
Perform the following labs to learn more about Actions migrations with Valet:
|
||||
|
||||
1. [Configure credentials for Valet](1-configure.md)
|
||||
2. [Perform an audit on GitLab pipelines](2-audit.md)
|
||||
3. [Perform a dry-run of a GitLab pipeline](3-dry-run.md)
|
||||
4. [Use custom transformers to customize Valet's behavior](4-custom-transformers.md)
|
||||
5. [Perform a production migration of a GitLab pipeline](5-migrate.md)
|
||||
6. [Forecast potential build runner usage](6-forecast.md)
|
||||
|
||||
## Troubleshoot the Valet CLI
|
||||
|
||||
The CLI extension for Valet can be manually installed by following these steps:
|
||||
|
||||
- Verify you are in the codespace terminal
|
||||
- Run this command from within the codespace's terminal:
|
||||
|
||||
```bash
|
||||
gh extension install github/gh-valet
|
||||
```
|
||||
|
||||
- Verify the result of the install contains:
|
||||
|
||||
```bash
|
||||
✓ Installed extension github/gh-valet
|
||||
```
|
||||
|
||||
- If you get an error similar to the image below, then click the link in the terminal output to authorize the token.
|
||||
- Restart the codespace after clicking the link.
|
||||

|
||||
- Verify Valet CLI extension is installed and working by running the following command from the codespace's terminal:
|
||||
|
||||
```bash
|
||||
gh valet version
|
||||
```
|
||||
@@ -4,10 +4,6 @@ In this lab, you will use the `configure` CLI command to set the required creden
|
||||
|
||||
You will need to complete all of the setup instructions [here](./readme.md#configure-your-codespace) prior to performing this lab.
|
||||
|
||||
- [Configuring credentials](#configuring-credentials)
|
||||
- [Verify your environment](#verify-your-environment)
|
||||
- [Next Lab](#next-lab)
|
||||
|
||||
## Configuring credentials
|
||||
|
||||
1. Open the Jenkins server in a new browser tab:
|
||||
@@ -43,6 +39,7 @@ You will need to complete all of the setup instructions [here](./readme.md#confi
|
||||
- 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 hit enter to accept the default value.
|
||||
|
||||

|
||||
|
||||
## Verify your environment
|
||||
@@ -65,6 +62,6 @@ To verify our environment is configured correctly, we are going to run the `upda
|
||||
ghcr.io/valet-customers/valet-cli:latest
|
||||
```
|
||||
|
||||
### Next Lab
|
||||
### Next lab
|
||||
|
||||
[Perform an audit of a Jenkins server](2-audit.md#perform-an-audit-of-a-jenkins-server)
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@
|
||||
|
||||
In this lab, you will use the `audit` command to get a high-level view of all pipelines in a Jenkins server.
|
||||
|
||||
This `audit` command operates by fetching all of the pipelines defined in a Jenkins server, converting each to their equivalent GitHub Actions workflow, and writing a report that summarizes how complete and complex of a migration is possible with Valet.
|
||||
The `audit` command operates by fetching all of the pipelines defined in a Jenkins server, converting each to their equivalent GitHub Actions workflow, and writing a report that summarizes how complete and complex of a migration is possible with Valet.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -11,7 +11,7 @@ This `audit` command operates by fetching all of the pipelines defined in a Jenk
|
||||
|
||||
## Perform an audit
|
||||
|
||||
We will be performing an audit against a preconfigured Jenkins server. We will need to answer the following questions before running this command:
|
||||
We will be performing an audit against your preconfigured Jenkins server. We will need to answer the following questions before running this command:
|
||||
|
||||
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 <folder_path>` flag to the audit command.
|
||||
@@ -61,7 +61,7 @@ Here are some key terms in the “Pipelines” section in the above example:
|
||||
- Valet encountered an internal error when converting it.
|
||||
- There was an unsuccessful network response, often due to invalid credentials, that caused the pipeline to be inaccessible.
|
||||
|
||||
The “Job types” section will summarize which types of pipelines are being used and which are supported or unsupported by Valet.
|
||||
The "Job types" section will summarize which types of pipelines are being used and which are supported or unsupported by Valet.
|
||||
|
||||
#### Build steps
|
||||
|
||||
@@ -69,7 +69,7 @@ The build steps summary section presents an overview of the individual build ste
|
||||
|
||||

|
||||
|
||||
Here are some key terms in the “Build steps” section in the above example:
|
||||
Here are some key terms in the "Build steps" section in the above example:
|
||||
|
||||
- A __known__ build step is a step that was automatically converted to an equivalent action.
|
||||
- An __unknown__ build step is a step that was not automatically converted to an equivalent action.
|
||||
|
||||
@@ -10,7 +10,7 @@ In this lab you will use the `dry-run` command to convert a Jenkins pipeline to
|
||||
|
||||
## Perform a dry-run
|
||||
|
||||
We will be performing a dry-run against a pipeline in the preconfigured Jenkins server. We will need to answer the following questions before running this command:
|
||||
We will be performing a dry-run against a pipeline in your preconfigured Jenkins server. We will need to answer the following questions before running this command:
|
||||
|
||||
1. What is the name of the pipeline we want to convert?
|
||||
- __test_pipeline__
|
||||
@@ -43,7 +43,7 @@ We will be performing a dry-run against a pipeline in the preconfigured Jenkins
|
||||
The files generated from the `dry-run` command represent the equivalent Actions workflow for the given Jenkins pipeline. The Jenkins pipeline and converted workflow can be seen below:
|
||||
|
||||
<details>
|
||||
<summary><em>Jenkins Pipeline 👇</em></summary>
|
||||
<summary><em>Jenkins pipeline 👇</em></summary>
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
|
||||
@@ -17,11 +17,11 @@ In this lab we will build upon the `dry-run` command to override Valet's default
|
||||
|
||||
We will be performing a `dry-run` command to inspect the workflow that is converted by default. Run the following command within the codespace terminal:
|
||||
|
||||
```bash
|
||||
gh valet dry-run jenkins --source-url http://localhost:8080/job/test_pipeline -o tmp/jenkins/dry-run
|
||||
```
|
||||
```bash
|
||||
gh valet dry-run jenkins --source-url http://localhost:8080/job/test_pipeline -o tmp/jenkins/dry-run
|
||||
```
|
||||
|
||||
The converted workflow that is generated by the above command can be seen below
|
||||
The converted workflow that is generated by the above command can be seen below:
|
||||
|
||||
<details>
|
||||
<summary><em>Converted workflow 👇</em></summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Forecast the runner usage of a Jenkins instance
|
||||
# Forecast potential build runner usage
|
||||
|
||||
In this lab you will use the `forecast` command to forecast potential GitHub Actions usage by computing metrics from completed pipeline runs in your Jenkins server.
|
||||
|
||||
|
||||
+9
-4
@@ -25,10 +25,15 @@ These steps **must** be completed prior to starting other labs.
|
||||
gh valet version
|
||||
```
|
||||
|
||||
- Verify the output is similar to the image below. The version information may differ than what is shown below.
|
||||
- If `gh valet version` did not produce similar output then please follow the troubleshooting [guide](#troubleshoot-the-valet-cli).
|
||||
- Verify the output is similar to below.
|
||||
|
||||
```bash
|
||||
gh version 2.14.3 (2022-07-26)
|
||||
gh valet github/gh-valet v0.1.12
|
||||
valet-cli unknown
|
||||
```
|
||||
|
||||

|
||||
- If `gh valet version` did not produce similar output then please follow the troubleshooting [guide](#troubleshoot-the-valet-cli).
|
||||
|
||||
## Bootstrap a Jenkins server
|
||||
|
||||
@@ -52,7 +57,7 @@ These steps **must** be completed prior to starting other labs.
|
||||
|
||||
## Labs for Jenkins
|
||||
|
||||
Perform the following labs to test-drive Valet
|
||||
Perform the following labs to learn more about Actions migrations with Valet:
|
||||
|
||||
1. [Configure credentials for Valet](1-configure.md)
|
||||
2. [Perform an audit of a Jenkins server](2-audit.md)
|
||||
|
||||
Reference in New Issue
Block a user