1
0
mirror of synced 2025-12-30 03:01:36 -05:00

Merge branch 'secret-scanning-reorg-megabranch' into am-stead-enabling

This commit is contained in:
Anne-Marie
2024-07-31 11:29:33 +01:00
committed by GitHub
109 changed files with 1238 additions and 497 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

View File

@@ -28,6 +28,7 @@ You can control whether links in text blocks on {% data variables.location.produ
* To enable underlines on links in text blocks, under "Link underlines", select **Show link underlines**.
* To disable underlines on links in text blocks, under "Link underlines", select **Hide link underlines**.
* To disable hovercards for previewing link content, deselect **Hovercards**.
{% endif %}

View File

@@ -1,5 +1,6 @@
---
title: About continuous deployment
shortTitle: Continuous deployment
intro: 'You can create custom continuous deployment (CD) workflows directly in your {% data variables.product.prodname_dotcom %} repository with {% data variables.product.prodname_actions %}.'
versions:
fpt: '*'
@@ -8,9 +9,9 @@ versions:
type: overview
redirect_from:
- /actions/deployment/about-continuous-deployment
- /actions/deployment/about-deployments/about-continuous-deployment
topics:
- CD
shortTitle: About continuous deployment
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -7,6 +7,7 @@ redirect_from:
- /actions/automating-your-workflow-with-github-actions/about-continuous-integration
- /actions/building-and-testing-code-with-continuous-integration/about-continuous-integration
- /actions/guides/about-continuous-integration
- /actions/automating-builds-and-tests/about-continuous-integration
versions:
fpt: '*'
ghes: '*'

View File

@@ -0,0 +1,14 @@
---
title: About GitHub Actions
shortTitle: About GitHub Actions
intro: '{% data variables.product.prodname_actions %} is a tool that you can use to build automations to assist with each stage of the software development lifecycle. This section describes {% data variables.product.prodname_actions %} concepts, common terminology, and some high level use cases.'
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /understanding-github-actions
- /about-continuous-integration
- /about-continuous-deployment
---

View File

@@ -7,6 +7,8 @@ redirect_from:
- /actions/automating-your-workflow-with-github-actions/core-concepts-for-github-actions
- /actions/getting-started-with-github-actions/core-concepts-for-github-actions
- /actions/learn-github-actions/introduction-to-github-actions
- /actions/learn-github-actions/understanding-github-actions
- /actions/learn-github-actions/essential-features-of-github-actions
versions:
fpt: '*'
ghes: '*'

View File

@@ -10,6 +10,5 @@ children:
- /usage-limits-billing-and-administration
- /viewing-github-actions-usage-metrics-for-your-organization
- /sharing-workflows-secrets-and-runners-with-your-organization
- /managing-environments-for-deployment
---

View File

@@ -16,7 +16,6 @@ redirect_from:
- /actions/guides/building-and-testing-nodejs-or-python
- /actions/automating-builds-and-tests/building-and-testing-nodejs-or-python
children:
- /about-continuous-integration
- /building-and-testing-go
- /building-and-testing-java-with-ant
- /building-and-testing-java-with-gradle

View File

@@ -7,7 +7,6 @@ versions:
ghes: '*'
ghec: '*'
children:
- /about-continuous-deployment
- /deploying-with-github-actions
---

View File

@@ -10,8 +10,6 @@ children:
- /about-deployments
- /deploying-to-your-cloud-provider
- /security-hardening-your-deployments
- /protecting-deployments
- /managing-your-deployments
- /deploying-xcode-applications
---

View File

@@ -1,12 +0,0 @@
---
title: Managing your deployments
shortTitle: Manage your deployments
intro: You can review the past activity of your deployments.
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /viewing-deployment-history
---

View File

@@ -1,13 +0,0 @@
---
title: Protecting your deployments with custom deployment protection rules
shortTitle: Protect deployments
intro: You can create and configure custom deployment protection rules to approve or reject deployments across environments with more control and confidence.
versions:
fpt: '*'
ghec: '*'
ghes: '*'
children:
- /creating-custom-deployment-protection-rules
- /configuring-custom-deployment-protection-rules
---

View File

@@ -1,5 +1,5 @@
---
title: Guides for {% data variables.product.prodname_actions %}
title: 'Guides for {% data variables.product.prodname_actions %}'
intro: 'These guides for {% data variables.product.prodname_actions %} include specific use cases and examples to help you configure workflows.'
allowTitleToDifferFromFilename: true
layout: product-guides
@@ -14,16 +14,16 @@ learningTracks:
- hosting_your_own_runners
- create_actions
includeGuides:
- /actions/quickstart
- /actions/learn-github-actions/understanding-github-actions
- /actions/writing-workflows/quickstart
- /actions/about-github-actions/understanding-github-actions
- /actions/creating-actions/creating-a-docker-container-action
- /actions/learn-github-actions/using-starter-workflows
- /actions/writing-workflows/using-starter-workflows
- /actions/automating-builds-and-tests/building-and-testing-python
- /actions/automating-builds-and-tests/building-and-testing-nodejs
- /actions/publishing-packages/about-packaging-with-github-actions
- /actions/publishing-packages/publishing-docker-images
- /actions/using-workflows/caching-dependencies-to-speed-up-workflows
- /actions/automating-builds-and-tests/about-continuous-integration
- /actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows
- /actions/about-github-actions/about-continuous-integration
- /actions/automating-builds-and-tests/building-and-testing-powershell
- /actions/automating-builds-and-tests/building-and-testing-ruby
- /actions/automating-builds-and-tests/building-and-testing-java-with-maven
@@ -35,13 +35,12 @@ includeGuides:
- /actions/publishing-packages/publishing-nodejs-packages
- /actions/publishing-packages/publishing-java-packages-with-maven
- /actions/publishing-packages/publishing-java-packages-with-gradle
- /actions/using-workflows/storing-workflow-data-as-artifacts
- /actions/writing-workflows/choosing-what-your-workflow-does/storing-workflow-data-as-artifacts
- /actions/using-containerized-services/about-service-containers
- /actions/using-containerized-services/creating-redis-service-containers
- /actions/using-containerized-services/creating-postgresql-service-containers
- /actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service
- /actions/deployment/deploying-to-your-cloud-provider/deploying-to-google-kubernetes-engine
- /actions/learn-github-actions/essential-features-of-github-actions
- /actions/security-guides/security-hardening-for-github-actions
- /actions/creating-actions/about-custom-actions
- /actions/creating-actions/creating-a-javascript-action
@@ -69,3 +68,4 @@ includeGuides:
- /actions/deployment/deploying-to-your-cloud-provider/deploying-to-azure/deploying-to-azure-static-web-app
- /actions/deployment/deploying-to-your-cloud-provider/deploying-to-azure/deploying-to-azure-kubernetes-service
---

View File

@@ -77,7 +77,7 @@ If you get a "permission denied" error when you attempt to run a script, make su
chmod +x PATH/TO/FILE
```
For information about using workflows to run scripts, see "[AUTOTITLE](/actions/learn-github-actions/essential-features-of-github-actions#adding-scripts-to-your-workflow)."
For information about using workflows to run scripts, see "[AUTOTITLE](/actions/writing-workflows/choosing-what-your-workflow-does/adding-scripts-to-your-workflow)."
### No timeout setting

View File

@@ -3,28 +3,28 @@ title: '{% data variables.product.prodname_actions %} documentation'
shortTitle: '{% data variables.product.prodname_actions %}'
intro: 'Automate, customize, and execute your software development workflows right in your repository with {% data variables.product.prodname_actions %}. You can discover, create, and share actions to perform any job you''d like, including CI/CD, and combine actions in a completely customized workflow.'
introLinks:
overview: /actions/learn-github-actions/understanding-github-actions
quickstart: /actions/quickstart
overview: /actions/about-github-actions/understanding-github-actions
quickstart: /actions/writing-workflows/quickstart
featuredLinks:
startHere:
- /actions/learn-github-actions
- /actions/writing-workflows
- /actions/examples
- /actions/automating-builds-and-tests/about-continuous-integration
- /actions/about-github-actions/about-continuous-integration
- /actions/deployment/about-deployments/deploying-with-github-actions
- /actions/publishing-packages/about-packaging-with-github-actions
- /actions/monitoring-and-troubleshooting-workflows
guideCards:
- /actions/learn-github-actions/using-starter-workflows
- /actions/writing-workflows/using-starter-workflows
- /actions/publishing-packages/publishing-nodejs-packages
- /actions/automating-builds-and-tests/building-and-testing-powershell
popular:
- /actions/using-workflows/workflow-syntax-for-github-actions
- /actions/learn-github-actions
- /actions/writing-workflows/workflow-syntax-for-github-actions
- /actions/writing-workflows
- /actions/examples
- /actions/using-workflows/events-that-trigger-workflows
- /actions/learn-github-actions/contexts
- /actions/learn-github-actions/expressions
- /actions/learn-github-actions/variables
- /actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows
- /actions/writing-workflows/choosing-what-your-workflow-does/contexts
- /actions/writing-workflows/choosing-what-your-workflow-does/expressions
- /actions/writing-workflows/choosing-what-your-workflow-does/variables
- /actions/security-guides/using-secrets-in-github-actions
changelog:
label: actions
@@ -42,12 +42,11 @@ versions:
ghes: '*'
ghec: '*'
children:
- /quickstart
- /learn-github-actions
- /about-github-actions
- /examples
- /writing-workflows
- /using-workflows
- /using-jobs
- /managing-workflow-runs
- /managing-workflow-runs-and-deployments
- /automating-builds-and-tests
- /deployment
- /using-containerized-services

View File

@@ -1,131 +0,0 @@
---
title: Essential features of GitHub Actions
shortTitle: Essential features
intro: '{% data variables.product.prodname_actions %} are designed to help you build robust and dynamic automations. This guide will show you how to craft {% data variables.product.prodname_actions %} workflows that include environment variables, customized scripts, and more.'
versions:
fpt: '*'
ghes: '*'
ghec: '*'
type: overview
topics:
- Fundamentals
---
{% data reusables.actions.enterprise-github-hosted-runners %}
## Overview
{% data variables.product.prodname_actions %} allow you to customize your workflows to meet the unique needs of your application and team. In this guide, we'll discuss some of the essential customization techniques such as using variables, running scripts, and sharing data and artifacts between jobs.
## Using variables in your workflows
{% data variables.product.prodname_actions %} include default environment variables for each workflow run. If you need to use custom environment variables, you can set these in your YAML workflow file. This example demonstrates how to create custom variables named `POSTGRES_HOST` and `POSTGRES_PORT`. These variables are then available to the `node client.js` script.
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- name: Connect to PostgreSQL
run: node client.js
env:
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
```
For more information, see "[AUTOTITLE](/actions/learn-github-actions/variables#default-environment-variables)."
## Adding scripts to your workflow
You can use a {% data variables.product.prodname_actions %} workflow to run scripts and shell commands, which are then executed on the assigned runner. This example demonstrates how to use the `run` keyword to execute the command `npm install -g bats` on the runner.
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- run: npm install -g bats
```
To use a workflow to run a script stored in your repository you must first check out the repository to the runner. Having done this, you can use the `run` keyword to run the script on the runner. The following example runs two scripts, each in a separate job step. The location of the scripts on the runner is specified by setting a default working directory for run commands. For more information, see "[AUTOTITLE](/actions/using-jobs/setting-default-values-for-jobs)."
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: Check out the repository to the runner
uses: {% data reusables.actions.action-checkout %}
- name: Run a script
run: ./my-script.sh
- name: Run another script
run: ./my-other-script.sh
```
Any scripts that you want a workflow job to run must be executable. You can do this either within the workflow by passing the script as an argument to the interpreter that will run the script - for example, `run: bash script.sh` - or by making the file itself executable. You can give the file the execute permission by using the command `git update-index --chmod=+x PATH/TO/YOUR/script.sh` locally, then committing and pushing the file to the repository. Alternatively, for workflows that are run on Linux and Mac runners, you can add a command to give the file the execute permission in the workflow job, prior to running the script:
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: Check out the repository to the runner
uses: {% data reusables.actions.action-checkout %}
- name: Make the script files executable
run: chmod +x my-script.sh my-other-script.sh
- name: Run the scripts
run: |
./my-script.sh
./my-other-script.sh
```
For more information about the `run` keyword, see "[AUTOTITLE](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun)."
## Sharing data between jobs
If your job generates files that you want to share with another job in the same workflow, or if you want to save the files for later reference, you can store them in {% data variables.product.prodname_dotcom %} as _artifacts_. Artifacts are the files created when you build and test your code. For example, artifacts might include binary or package files, test results, screenshots, or log files. Artifacts are associated with the workflow run where they were created and can be used by another job. {% data reusables.actions.reusable-workflow-artifacts %}
For example, you can create a file and then upload it as an artifact.
```yaml
jobs:
example-job:
name: Save output
runs-on: ubuntu-latest
steps:
- shell: bash
run: |
expr 1 + 1 > output.log
- name: Upload output file
uses: {% data reusables.actions.action-upload-artifact %}
with:
name: output-log-file
path: output.log
```
To download an artifact from a separate workflow run, you can use the `actions/download-artifact` action. For example, you can download the artifact named `output-log-file`.
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- name: Download a single artifact
uses: {% data reusables.actions.action-download-artifact %}
with:
name: output-log-file
```
To download an artifact from the same workflow run, your download job should specify `needs: upload-job-name` so it doesn't start until the upload job finishes.
For more information about artifacts, see "[AUTOTITLE](/actions/using-workflows/storing-workflow-data-as-artifacts)."
## Next steps
To continue learning about {% data variables.product.prodname_actions %}, see "[AUTOTITLE](/actions/using-workflows/about-workflows)."

View File

@@ -1,29 +0,0 @@
---
title: Learn GitHub Actions
shortTitle: Learn GitHub Actions
intro: 'Whether you are new to {% data variables.product.prodname_actions %} or interested in learning all they have to offer, this guide will help you use {% data variables.product.prodname_actions %} to accelerate your application development workflows.'
redirect_from:
- /articles/about-github-actions
- /actions/getting-started-with-github-actions
- /actions/getting-started-with-github-actions/about-github-actions
- /actions/getting-started-with-github-actions/overview
- /actions/getting-started-with-github-actions/getting-started-with-github-actions
- /articles/getting-started-with-github-actions
- /github/automating-your-workflow-with-github-actions/about-github-actions
- /actions/automating-your-workflow-with-github-actions/about-github-actions
- /github/automating-your-workflow-with-github-actions/getting-started-with-github-actions
- /actions/automating-your-workflow-with-github-actions/getting-started-with-github-actions
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /understanding-github-actions
- /finding-and-customizing-actions
- /essential-features-of-github-actions
- /expressions
- /contexts
- /variables
- /using-starter-workflows
---

View File

@@ -0,0 +1,21 @@
---
title: Managing workflow runs and deployments
shortTitle: Manage workflows and deployments
intro: '{% data variables.product.prodname_dotcom %} enables you to have control over your workflow runs and deployments.'
redirect_from:
- /actions/configuring-and-managing-workflows/managing-a-workflow-run
- /articles/managing-a-workflow-run
- /github/automating-your-workflow-with-github-actions/managing-a-workflow-run
- /actions/automating-your-workflow-with-github-actions/managing-a-workflow-run
- /actions/configuring-and-managing-workflows/configuring-and-managing-workflow-files-and-runs
- /actions/managing-workflow-runs
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /managing-workflow-runs
- /managing-deployments
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -11,6 +11,8 @@ topics:
- Actions
- CD
- Deployment
redirect_from:
- /actions/deployment/protecting-deployments/configuring-custom-deployment-protection-rules
---
{% data reusables.actions.custom-deployment-protection-rules-beta-note %}

View File

@@ -11,6 +11,8 @@ topics:
- Actions
- CD
- Deployment
redirect_from:
- /actions/deployment/protecting-deployments/creating-custom-deployment-protection-rules
---
{% data reusables.actions.custom-deployment-protection-rules-beta-note %}

View File

@@ -0,0 +1,19 @@
---
title: Managing deployments
shortTitle: Manage deployments
intro: 'View your deployment history and configure rules to protect your deployments.'
redirect_from:
- /actions/deployment/managing-your-deployments
- /actions/deployment/protecting-deployments
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /viewing-deployment-history
- /managing-environments-for-deployment
- /reviewing-deployments
- /creating-custom-deployment-protection-rules
- /configuring-custom-deployment-protection-rules
---

View File

@@ -11,6 +11,7 @@ redirect_from:
- /actions/deployment/targeting-different-environments/using-environments-for-deployment
- /actions/deployment/targeting-different-environments
- /actions/deployment/targeting-different-environments/managing-environments-for-deployment
- /actions/administering-github-actions/managing-environments-for-deployment
topics:
- CD
- Deployment

View File

@@ -7,6 +7,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/managing-workflow-runs/reviewing-deployments
---

View File

@@ -11,6 +11,7 @@ topics:
redirect_from:
- /developers/overview/viewing-deployment-history
- /actions/deployment/viewing-deployment-history
- /actions/deployment/managing-your-deployments/viewing-deployment-history
---
{% ifversion actions-deployment-history-beta %}

View File

@@ -5,6 +5,8 @@ permissions: Maintainers with write access to a repository can approve workflow
versions:
feature: actions-private-fork-workflow-approvals
shortTitle: Approve private fork runs
redirect_from:
- /actions/managing-workflow-runs/approving-workflow-runs-from-private-forks
---
## About workflow runs from private forks

View File

@@ -5,6 +5,8 @@ versions:
fpt: '*'
ghec: '*'
shortTitle: Approve public fork runs
redirect_from:
- /actions/managing-workflow-runs/approving-workflow-runs-from-public-forks
---
## About workflow runs from public forks

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/managing-workflow-runs/canceling-a-workflow
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/managing-workflow-runs/deleting-a-workflow-run
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -8,6 +8,7 @@ versions:
shortTitle: Disable & enable a workflow
redirect_from:
- /actions/managing-workflow-runs/disabling-and-enabling-a-workflow
- /actions/using-workflows/disabling-and-enabling-a-workflow
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -7,6 +7,8 @@ versions:
ghes: '*'
ghec: '*'
shortTitle: Download workflow artifacts
redirect_from:
- /actions/managing-workflow-runs/downloading-workflow-artifacts
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -0,0 +1,21 @@
---
title: Managing workflow runs
shortTitle: Manage workflow runs
intro: 'You can manually interact with workflow runs to ensure they run effectively.'
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /manually-running-a-workflow
- /re-running-workflows-and-jobs
- /canceling-a-workflow
- /disabling-and-enabling-a-workflow
- /skipping-workflow-runs
- /deleting-a-workflow-run
- /downloading-workflow-artifacts
- /removing-workflow-artifacts
- /approving-workflow-runs-from-public-forks
- /approving-workflow-runs-from-private-forks
---

View File

@@ -8,6 +8,7 @@ versions:
shortTitle: Manually run a workflow
redirect_from:
- /actions/managing-workflow-runs/manually-running-a-workflow
- /actions/using-workflows/manually-running-a-workflow
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -5,6 +5,7 @@ intro: 'You can re-run a workflow run{% ifversion re-run-jobs %}, all failed job
permissions: People with write permissions to a repository can re-run workflows in the repository.
redirect_from:
- /actions/managing-workflow-runs/re-running-a-workflow
- /actions/managing-workflow-runs/re-running-workflows-and-jobs
versions:
fpt: '*'
ghes: '*'

View File

@@ -6,6 +6,8 @@ versions:
ghes: '*'
ghec: '*'
shortTitle: Remove workflow artifacts
redirect_from:
- /actions/managing-workflow-runs/removing-workflow-artifacts
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -6,6 +6,8 @@ versions:
ghes: '*'
ghec: '*'
shortTitle: Skip workflow runs
redirect_from:
- /actions/managing-workflow-runs/skipping-workflow-runs
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -1,27 +0,0 @@
---
title: Managing workflow runs
shortTitle: Manage workflow runs
intro: 'You can re-run or cancel a workflow, {% ifversion fpt or ghes %}review deployments, {% endif %}view billable job execution minutes, and download artifacts.'
redirect_from:
- /actions/configuring-and-managing-workflows/managing-a-workflow-run
- /articles/managing-a-workflow-run
- /github/automating-your-workflow-with-github-actions/managing-a-workflow-run
- /actions/automating-your-workflow-with-github-actions/managing-a-workflow-run
- /actions/configuring-and-managing-workflows/configuring-and-managing-workflow-files-and-runs
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /re-running-workflows-and-jobs
- /canceling-a-workflow
- /approving-workflow-runs-from-public-forks
- /approving-workflow-runs-from-private-forks
- /reviewing-deployments
- /skipping-workflow-runs
- /deleting-a-workflow-run
- /downloading-workflow-artifacts
- /removing-workflow-artifacts
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -447,4 +447,27 @@ You can use Base64 encoding to store small binary blobs as secrets. You can then
## Redacting secrets from workflow run logs
While {% data variables.product.prodname_dotcom %} automatically redacts secrets printed to workflow logs, runners can only delete secrets they have access to. This means a secret will only be redacted if it was used within a job. As a security measure, you can delete workflow run logs to prevent sensitive values being leaked. For more information, see "[AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/using-workflow-run-logs#deleting-logs)."
{% data variables.product.prodname_actions %} automatically redacts the contents of all {% data variables.product.prodname_dotcom %} secrets that are printed to workflow logs.
{% data variables.product.prodname_actions %} also redacts information that is recognized as sensitive, but is not stored as a secret. Currently {% data variables.product.prodname_dotcom %} supports the following:
* 32-byte and 64-byte Azure keys
* Azure AD client app passwords
* Azure Cache keys
* Azure Container Registry keys
* Azure Function host keys
* Azure Search keys
* Database connection strings
* HTTP Bearer token headers
* JWTs
* NPM author tokens
* NuGet API keys
* v1 GitHub installation tokens
* v2 GitHub installation tokens (`ghp`, `gho`, `ghu`, `ghs`, `ghr`)
* v2 GitHub PATs
> [!NOTE] If you would like other types of sensitive information to be automatically redacted, please reach out to us in our [community discussions](https://github.com/orgs/community/discussions?discussions_q=is%3Aopen+label%3AActions).
As a habit of best practice, you should mask all sensitive information that is not a {% data variables.product.prodname_dotcom %} secret by using `::add-mask::VALUE`. This causes the value to be treated as a secret and redacted from logs. For more information about masking data, see "[AUTOTITLE](/actions/using-workflows/workflow-commands-for-github-actions#masking-a-value-in-a-log)."
Redacting of secrets is performed by your workflow runners. This means a secret will only be redacted if it was used within a job and is accessible by the runner. If an unredacted secret is sent to a workflow run log, you should delete the log and rotate the secret. For information on deleting logs, see "[AUTOTITLE](/actions/monitoring-and-troubleshooting-workflows/using-workflow-run-logs#deleting-logs)."

View File

@@ -1,23 +0,0 @@
---
title: Using jobs
shortTitle: Using jobs
intro: 'Creating and managing {% data variables.product.prodname_actions %} jobs.'
redirect_from:
- /actions/jobs
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /using-jobs-in-a-workflow
- /choosing-the-runner-for-a-job
- /using-conditions-to-control-job-execution
- /using-a-matrix-for-your-jobs
- /using-concurrency
- /using-environments-for-deployment
- /running-jobs-in-a-container
- /setting-default-values-for-jobs
- /assigning-permissions-to-jobs
- /defining-outputs-for-jobs
---

View File

@@ -21,18 +21,9 @@ versions:
ghec: '*'
children:
- /about-workflows
- /triggering-a-workflow
- /manually-running-a-workflow
- /disabling-and-enabling-a-workflow
- /events-that-trigger-workflows
- /workflow-syntax-for-github-actions
- /workflow-commands-for-github-actions
- /avoiding-duplication
- /reusing-workflows
- /required-workflows
- /caching-dependencies-to-speed-up-workflows
- /storing-workflow-data-as-artifacts
- /creating-starter-workflows-for-your-organization
- /using-github-cli-in-workflows
---

View File

@@ -0,0 +1,59 @@
---
title: Adding scripts to your workflow
shortTitle: Add scripts
intro: 'You can use {% data variables.product.prodname_actions %} workflows to run scripts.'
versions:
fpt: '*'
ghes: '*'
ghec: '*'
---
You can use a {% data variables.product.prodname_actions %} workflow to run scripts and shell commands, which are then executed on the assigned runner. This example demonstrates how to use the `run` keyword to execute the command `npm install -g bats` on the runner.
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- run: npm install -g bats
```
To use a workflow to run a script stored in your repository you must first check out the repository to the runner. Having done this, you can use the `run` keyword to run the script on the runner. The following example runs two scripts, each in a separate job step. The location of the scripts on the runner is specified by setting a default working directory for run commands. For more information, see "[AUTOTITLE](/actions/using-jobs/setting-default-values-for-jobs)."
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: Check out the repository to the runner
uses: {% data reusables.actions.action-checkout %}
- name: Run a script
run: ./my-script.sh
- name: Run another script
run: ./my-other-script.sh
```
Any scripts that you want a workflow job to run must be executable. You can do this either within the workflow by passing the script as an argument to the interpreter that will run the script - for example, `run: bash script.sh` - or by making the file itself executable. You can give the file the execute permission by using the command `git update-index --chmod=+x PATH/TO/YOUR/script.sh` locally, then committing and pushing the file to the repository. Alternatively, for workflows that are run on Linux and Mac runners, you can add a command to give the file the execute permission in the workflow job, prior to running the script:
```yaml
jobs:
example-job:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: Check out the repository to the runner
uses: {% data reusables.actions.action-checkout %}
- name: Make the script files executable
run: chmod +x my-script.sh my-other-script.sh
- name: Run the scripts
run: |
./my-script.sh
./my-other-script.sh
```
For more information about the `run` keyword, see "[AUTOTITLE](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun)."

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '> 3.1'
ghec: '*'
redirect_from:
- /actions/using-jobs/assigning-permissions-to-jobs
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -8,6 +8,7 @@ redirect_from:
- /actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows
- /actions/guides/caching-dependencies-to-speed-up-workflows
- /actions/advanced-guides/caching-dependencies-to-speed-up-workflows
- /actions/using-workflows/caching-dependencies-to-speed-up-workflows
versions:
feature: actions-caching
type: tutorial

View File

@@ -8,6 +8,7 @@ redirect_from:
- /actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions
- /actions/reference/contexts-and-expression-syntax-for-github-actions
- /actions/reference/context-and-expression-syntax-for-github-actions
- /actions/learn-github-actions/contexts
versions:
fpt: '*'
ghes: '*'

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/using-jobs/defining-outputs-for-jobs
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/learn-github-actions/expressions
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -7,6 +7,7 @@ redirect_from:
- /actions/automating-your-workflow-with-github-actions/using-actions-from-github-marketplace-in-your-workflow
- /actions/getting-started-with-github-actions/using-actions-from-github-marketplace
- /actions/getting-started-with-github-actions/using-community-workflows-and-actions
- /actions/learn-github-actions/finding-and-customizing-actions
versions:
fpt: '*'
ghes: '*'

View File

@@ -0,0 +1,29 @@
---
title: Choosing what your workflow does
shortTitle: Choose what workflows do
intro: 'Workflows automate tasks in your software development lifecycle. Many tasks that you manually complete can be converted to a {% data variables.product.prodname_actions %} workflow.'
redirect_from:
- /actions/using-jobs
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /using-jobs-in-a-workflow
- /finding-and-customizing-actions
- /using-github-cli-in-workflows
- /workflow-commands-for-github-actions
- /adding-scripts-to-your-workflow
- /assigning-permissions-to-jobs
- /expressions
- /variables
- /contexts
- /defining-outputs-for-jobs
- /setting-default-values-for-jobs
- /using-environments-for-deployment
- /using-concurrency
- /using-a-matrix-for-your-jobs
- /caching-dependencies-to-speed-up-workflows
- /storing-workflow-data-as-artifacts
---

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/using-jobs/setting-default-values-for-jobs
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -9,6 +9,7 @@ redirect_from:
- /actions/configuring-and-managing-workflows/persisting-workflow-data-using-artifacts
- /actions/guides/storing-workflow-data-as-artifacts
- /actions/advanced-guides/storing-workflow-data-as-artifacts
- /actions/using-workflows/storing-workflow-data-as-artifacts
versions:
fpt: '*'
ghes: '*'

View File

@@ -8,6 +8,7 @@ versions:
ghec: '*'
redirect_from:
- /actions/using-jobs/using-a-build-matrix-for-your-jobs
- /actions/using-jobs/using-a-matrix-for-your-jobs
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '> 3.1'
ghec: '*'
redirect_from:
- /actions/using-jobs/using-concurrency
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -8,6 +8,7 @@ versions:
ghec: '*'
redirect_from:
- /actions/using-jobs/using-environments-for-jobs
- /actions/using-jobs/using-environments-for-deployment
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -5,6 +5,7 @@ intro: 'You can script with {% data variables.product.prodname_cli %} in {% data
redirect_from:
- /actions/guides/using-github-cli-in-workflows
- /actions/advanced-guides/using-github-cli-in-workflows
- /actions/using-workflows/using-github-cli-in-workflows
versions:
fpt: '*'
ghes: '*'

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/using-jobs/using-jobs-in-a-workflow
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -7,6 +7,7 @@ redirect_from:
- /actions/configuring-and-managing-workflows/using-environment-variables
- /actions/reference/environment-variables
- /actions/learn-github-actions/environment-variables
- /actions/learn-github-actions/variables
versions:
fpt: '*'
ghes: '*'

View File

@@ -11,6 +11,7 @@ redirect_from:
- /actions/reference/logging-commands-for-github-actions
- /actions/reference/workflow-commands-for-github-actions
- /actions/learn-github-actions/workflow-commands-for-github-actions
- /actions/using-workflows/workflow-commands-for-github-actions
versions:
fpt: '*'
ghes: '*'

View File

@@ -7,6 +7,7 @@ redirect_from:
- /actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows
- /actions/reference/events-that-trigger-workflows
- /actions/learn-github-actions/events-that-trigger-workflows
- /actions/using-workflows/events-that-trigger-workflows
versions:
fpt: '*'
ghes: '*'

View File

@@ -0,0 +1,14 @@
---
title: Choosing when your workflow runs
shortTitle: Choose when workflows run
intro: You can configure workflows to run on a schedule or to run when certain events happen.
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /triggering-a-workflow
- /using-conditions-to-control-job-execution
- /events-that-trigger-workflows
---

View File

@@ -11,6 +11,8 @@ topics:
- Workflows
- CI
- CD
redirect_from:
- /actions/using-workflows/triggering-a-workflow
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/using-jobs/using-conditions-to-control-job-execution
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/using-jobs/choosing-the-runner-for-a-job
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -0,0 +1,13 @@
---
title: Choosing where your workflow runs
shortTitle: Choose where workflows run
intro: You can specify the compute environment your jobs and workflows run in.
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /choosing-the-runner-for-a-job
- /running-jobs-in-a-container
---

View File

@@ -6,6 +6,8 @@ versions:
fpt: '*'
ghes: '*'
ghec: '*'
redirect_from:
- /actions/using-jobs/running-jobs-in-a-container
---
{% data reusables.actions.enterprise-github-hosted-runners %}

View File

@@ -0,0 +1,19 @@
---
title: Writing workflows
shortTitle: Write workflows
intro: '{% data variables.product.prodname_actions %} workflows can automate tasks throughout the software development lifecycle.'
redirect_from:
- /actions/learn-github-actions
versions:
fpt: '*'
ghes: '*'
ghec: '*'
children:
- /quickstart
- /using-starter-workflows
- /choosing-when-your-workflow-runs
- /choosing-where-your-workflow-runs
- /choosing-what-your-workflow-does
- /workflow-syntax-for-github-actions
---

View File

@@ -4,6 +4,7 @@ intro: 'Try out the features of {% data variables.product.prodname_actions %} in
allowTitleToDifferFromFilename: true
redirect_from:
- /actions/getting-started-with-github-actions/starting-with-preconfigured-workflow-templates
- /actions/quickstart
versions:
fpt: '*'
ghes: '*'

View File

@@ -10,6 +10,7 @@ redirect_from:
- /actions/guides/setting-up-continuous-integration-using-workflow-templates
- /actions/learn-github-actions/using-workflow-templates
- /actions/using-workflows/using-starter-workflows
- /actions/learn-github-actions/using-starter-workflows
versions:
fpt: '*'
ghes: '*'

View File

@@ -8,6 +8,7 @@ redirect_from:
- /actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions
- /actions/reference/workflow-syntax-for-github-actions
- /actions/learn-github-actions/workflow-syntax-for-github-actions
- /actions/using-workflows/workflow-syntax-for-github-actions
versions:
fpt: '*'
ghes: '*'
@@ -683,7 +684,7 @@ Using the `working-directory` keyword, you can specify the working directory of
Alternatively, you can specify a default working directory for all `run` steps in a job, or for all `run` steps in the entire workflow. For more information, see "[`defaults.run.working-directory`](/actions/using-workflows/workflow-syntax-for-github-actions#defaultsrunworking-directory)" and "[`jobs.<job_id>.defaults.run.working-directory`](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_iddefaultsrunworking-directory)."
You can also use a `run` step to run a script. For more information, see "[AUTOTITLE](/actions/learn-github-actions/essential-features-of-github-actions#adding-scripts-to-your-workflow)."
You can also use a `run` step to run a script. For more information, see "[AUTOTITLE](/actions/writing-workflows/choosing-what-your-workflow-does/adding-scripts-to-your-workflow)."
## `jobs.<job_id>.steps[*].shell`

View File

@@ -166,7 +166,7 @@ To replace a node in an emergency, install the {% data variables.product.product
## Replacing the primary MySQL node
To provide database services, your cluster requires a primary MySQL node and at least one secondary MySQL node. For more information, see "[AUTOTITLE](/admin/monitoring-managing-and-updating-your-instance/configuring-clustering/about-cluster-nodes)."
To provide database services, your cluster requires a primary MySQL node and at least one replica MySQL node. For more information, see "[AUTOTITLE](/admin/monitoring-managing-and-updating-your-instance/configuring-clustering/about-cluster-nodes)."
If you want to provide the VM for your primary MySQL node with more resources, or if the node fails, you can replace the node. To minimize downtime, add the new node to your cluster, replicate the MySQL data, and then promote the node. Some downtime is required during promotion.
@@ -194,10 +194,10 @@ If you want to provide the VM for your primary MySQL node with more resources, o
</pre>
{% data reusables.enterprise_clustering.replacing-a-cluster-node-initialize-new-node %}
{% data reusables.enterprise_clustering.replacing-a-cluster-node-validate-config %}
1. From the administrative shell of the node where you modified `cluster.conf`, run `ghe-cluster-config-apply`. The newly added node will become a replica MySQL node and any other configured services will run there.
1. Wait for MySQL replication to finish. To monitor MySQL replication from any node in the cluster, run `ghe-cluster-status -v`.
Shortly after adding the node to the cluster, you may see an error for replication status while replication catches up. Replication can take hours depending on the instance's load and the last time the instance generated a database seed.
Shortly after adding the node to the cluster, you may see an error for replication status while replication catches up. Replication can take hours depending on the instance's load, the amount of database data, and the last time the instance generated a database seed.
1. During your scheduled maintenance window, enable maintenance mode. For more information, see "[AUTOTITLE](/admin/administering-your-instance/configuring-maintenance-mode/enabling-and-scheduling-maintenance-mode#enabling-or-disabling-maintenance-mode-for-all-nodes-in-a-cluster-via-the-cli)."
1. Ensure that MySQL replication is finished from any node in the cluster by running `ghe-cluster-status -v`.
@@ -212,13 +212,13 @@ If you want to provide the VM for your primary MySQL node with more resources, o
echo "SET GLOBAL super_read_only = 1;" | sudo mysql
```
1. Wait until Global Transaction Identifiers (GTIDs) set on the primary and secondary MySQL nodes are identical. To check the GTIDs, run the following command from any of the instance's nodes.
1. Wait until Global Transaction Identifiers (GTIDs) set on the primary and replica MySQL nodes are identical. To check the GTIDs, run the following command from any of the instance's nodes.
```shell copy
ghe-cluster-each -r mysql -- 'echo "SELECT @@global.gtid_executed;" | sudo mysql'
```
1. After the GTIDs on the primary and secondary MySQL nodes match, update the cluster configuration by opening the cluster configuration file at `/data/user/common/cluster.conf` in a text editor.
1. After the GTIDs on the primary and replica MySQL nodes match, update the cluster configuration by opening the cluster configuration file at `/data/user/common/cluster.conf` in a text editor.
* Create a backup of the `cluster.conf` file before you edit the file.
* In the top-level `[cluster]` section, remove the hostname for the node you replaced from the `mysql-master` key-value pair, then assign the new node instead. If the new node is also a primary Redis node, adjust the `redis-master` key-value pair.
@@ -230,6 +230,6 @@ If you want to provide the VM for your primary MySQL node with more resources, o
primary-datacenter = primary
...
</pre>
{% data reusables.enterprise_clustering.replacing-a-cluster-node-validate-config %}
1. From the administrative shell of the node where you modified `cluster.conf`, run `ghe-cluster-config-apply`. This will reconfigure the cluster so that the newly added node becomes the primary MySQL node and the original primary MySQL node becomes a replica MySQL node.
1. Check the status of MySQL replication from any node in the cluster by running `ghe-cluster-status -v`.
1. If MySQL replication is finished, from any node in the cluster, disable maintenance mode. For more information, see "[AUTOTITLE](/admin/administering-your-instance/configuring-maintenance-mode/enabling-and-scheduling-maintenance-mode#enabling-or-disabling-maintenance-mode-for-all-nodes-in-a-cluster-via-the-cli)."

View File

@@ -44,7 +44,7 @@ When verifying a signature, {% data variables.product.product_name %} extracts t
1. In the "Title" field, type a name for your GPG key.
1. In the "Key" field, paste the GPG key you copied when you [generated your GPG key](/authentication/managing-commit-signature-verification/generating-a-new-gpg-key).
1. Click **Add GPG key**.
1. To confirm the action, authenticate to your {% data variables.product.prodname_dotcom %} account.
1. If prompted, authenticate to your {% data variables.product.prodname_dotcom %} account to confirm the action.
{% ifversion upload-expired-or-revoked-gpg-key %}
{% else %}

View File

@@ -21,6 +21,12 @@ shortTitle: Advanced Security billing
## About licenses for {% data variables.product.prodname_GH_advanced_security %}
{% ifversion billing-auth-and-capture %}
{% data reusables.billing.authorization-charge %}
{% endif %}
{% ifversion fpt %}
{% data reusables.advanced-security.ghas-license-info-for-fpt %}

View File

@@ -17,6 +17,12 @@ shortTitle: Billing for GitHub Copilot
## About billing for {% data variables.product.prodname_copilot_short %}
{% ifversion billing-auth-and-capture %}
{% data reusables.billing.authorization-charge %}
{% endif %}
You can set up a {% data variables.product.prodname_copilot %} subscription for your personal account, or for an organization or enterprise.
* **For your personal account**, you can set up a subscription to {% data variables.product.prodname_copilot_for_individuals %}.

View File

@@ -23,6 +23,8 @@ By default, {% data variables.product.prodname_copilot %} connects to {% data va
Some networks use an HTTP proxy server to intercept Internet traffic before sending it to its intended location. Companies often use an HTTP proxy to detect suspicious traffic or restrict the content entering their networks. If you're working on a corporate network, you may need to configure {% data variables.product.prodname_copilot_short %} to connect via an HTTP proxy.
> [!NOTE] The administrator of your proxy server or firewall also needs to configure network settings for {% data variables.product.prodname_copilot_short %} to work as expected. See "[AUTOTITLE](/copilot/managing-copilot/managing-github-copilot-in-your-organization/configuring-your-proxy-server-or-firewall-for-copilot)."
## Configuring proxy settings for {% data variables.product.prodname_copilot %}
{% data variables.product.prodname_copilot %} supports basic HTTP proxy setups. If you need to authenticate to a proxy, {% data variables.product.prodname_copilot %} supports basic authentication or authentication with Kerberos. If the proxy URL starts `https://`, the proxy is not currently supported.

View File

@@ -0,0 +1,33 @@
---
title: Configuring your proxy server or firewall for Copilot
intro: 'You should allow certain traffic through your firewall or proxy server for {% data variables.product.prodname_copilot_short %} to work as intended.'
permissions: 'Proxy server maintainers or firewall maintainers'
product: '{% data reusables.gated-features.copilot %}'
versions:
feature: copilot
topics:
- Copilot
shortTitle: Allow Copilot traffic
---
If your company employs security measures like a firewall or proxy server, you should add the following URLs, ports, and protocols to an allowlist to ensure {% data variables.product.prodname_copilot_short %} works as expected:
| Domain and/or URL | Purpose |
| :------------------------------------- | :--------------------------------- |
| `https://github.com/login/*` | Authentication |
| `https://api.github.com/user` | User Management |
| `https://api.github.com/copilot_internal/*` | User Management |
| `https://copilot-telemetry.githubusercontent.com/telemetry` | Telemetry |
| `https://default.exp-tas.com/` | Telemetry |
| `https://copilot-proxy.githubusercontent.com/` | API service for {% data variables.product.prodname_copilot_short %} suggestions |
| `https://origin-tracker.githubusercontent.com` | API service for {% data variables.product.prodname_copilot_short %} suggestions |
| `https://*.githubcopilot.com` | API service for {% data variables.product.prodname_copilot_short %} suggestions |
Depending on the security policies and editors your organization uses, you may need to allowlist additional domains and URLs. For more information on specific editors, see "[Further reading](#further-reading)."
Every user of the proxy server or firewall also needs to configure their own environment to connect to {% data variables.product.prodname_copilot_short %}. See "[AUTOTITLE](/copilot/configuring-github-copilot/configuring-network-settings-for-github-copilot)."
## Further reading
* [Network Connections in {% data variables.product.prodname_vscode %}](https://code.visualstudio.com/docs/setup/network) in the {% data variables.product.prodname_vs %} documentation
* [Install and use {% data variables.product.prodname_vs %} and Azure Services behind a firewall or proxy server](https://learn.microsoft.com/en-us/visualstudio/install/install-and-use-visual-studio-behind-a-firewall-or-proxy-server) in the Microsoft documentation

View File

@@ -12,6 +12,7 @@ topics:
children:
- /managing-the-copilot-subscription-for-your-organization
- /setting-policies-for-copilot-in-your-organization
- /configuring-your-proxy-server-or-firewall-for-copilot
- /managing-access-to-github-copilot-in-your-organization
- /enhancing-copilot-for-your-organization
---

View File

@@ -24,9 +24,9 @@ Control which {% data variables.product.prodname_copilot_short %} features are a
## 3. Set up networking (if necessary)
If your enterprise users connect through an HTTP proxy server or firewall, ensure that [these URLs](/copilot/troubleshooting-github-copilot/troubleshooting-firewall-settings-for-github-copilot#urls-to-add-to-an-allowlist) are added to the allowlist for the proxy server or firewall.
If your enterprise users connect through an HTTP proxy server or firewall, ensure that key URLs are added to the allowlist for the proxy server or firewall. See "[AUTOTITLE](/copilot/managing-copilot/managing-github-copilot-in-your-organization/configuring-your-proxy-server-or-firewall-for-copilot)."
You may also need to install custom SSL certificates on your users' machines. See "[AUTOTITLE](/copilot/managing-copilot/configure-personal-settings/configuring-network-settings-for-github-copilot)."
You may also need to install custom SSL certificates on your users' machines. See "[AUTOTITLE](/copilot/managing-copilot/configure-personal-settings/configuring-network-settings-for-github-copilot#installing-custom-certificates)."
## 4. Grant access to organizations

View File

@@ -27,9 +27,9 @@ Control which {% data variables.product.prodname_copilot_short %} features are a
## 3. Set up networking (if necessary)
If your organization members connect through an HTTP proxy server or firewall, ensure that [these URLs](/copilot/troubleshooting-github-copilot/troubleshooting-firewall-settings-for-github-copilot#urls-to-add-to-an-allowlist) are added to the allowlist for the proxy server or firewall.
If your organization members connect through an HTTP proxy server or firewall, ensure that key URLs are added to the allowlist for the proxy server or firewall. See "[AUTOTITLE](/copilot/managing-copilot/managing-github-copilot-in-your-organization/configuring-your-proxy-server-or-firewall-for-copilot)."
You may also need to install custom SSL certificates on your members' machines. See "[AUTOTITLE](/copilot/managing-copilot/configure-personal-settings/configuring-network-settings-for-github-copilot)."
You may also need to install custom SSL certificates on your members' machines. See "[AUTOTITLE](/copilot/managing-copilot/configure-personal-settings/configuring-network-settings-for-github-copilot#-installing-custom-certificates)."
## 4. Grant access to members

View File

@@ -28,9 +28,9 @@ If you want to use {% data variables.product.prodname_copilot_short %} in the co
## 4. Set up networking (if necessary)
If you connect through an HTTP proxy server or firewall, ensure that [these URLs](/copilot/troubleshooting-github-copilot/troubleshooting-firewall-settings-for-github-copilot#urls-to-add-to-an-allowlist) are added to the allowlist for the proxy server or firewall.
If you connect through an HTTP proxy server or firewall, ensure that key URLs are added to the allowlist for the proxy server or firewall. See "[AUTOTITLE](/copilot/managing-copilot/managing-github-copilot-in-your-organization/configuring-your-proxy-server-or-firewall-for-copilot)."
You may also need to install a custom SSL certificate on your machine. See "[AUTOTITLE](/copilot/managing-copilot/configure-personal-settings/configuring-network-settings-for-github-copilot)."
You may also need to install a custom SSL certificate on your machine. See "[AUTOTITLE](/copilot/managing-copilot/configure-personal-settings/configuring-network-settings-for-github-copilot#installing-custom-certificates)."
## 5. Configure settings (optional)

View File

@@ -8,30 +8,13 @@ topics:
- Networking
versions:
feature: copilot
shortTitle: Firewall settings
shortTitle: Connectivity security settings
---
If you or your organization employs security measures like a firewall or proxy server, it may be beneficial to include certain domain URLs in an "allowlist" and open specific ports and protocols. Doing so will enhance your installation and usage of {% data variables.product.prodname_copilot_short %} for an optimal experience.
## About the problem
## URLs to add to an allowlist
If you or your company uses a firewall, {% data variables.product.prodname_copilot_short %} may not function as expected. {% data variables.product.prodname_copilot_short %} interacts with a remote machine learning model and checks for updates, and a firewall may block important traffic and degrade the user experience.
Due to {% data variables.product.prodname_copilot_short %}'s interaction with a remote machine learning model and its update-checking functionality, it is recommended to include the following domain URLs in the allowlist, marking them as trusted either in the user interface or within your deployment scripts.
## Solving the problem
| Domain and/or URL | Purpose |
| :------------------------------------- | :--------------------------------- |
| `https://github.com/login/*` | Authentication |
| `https://api.github.com/user` | User Management |
| `https://api.github.com/copilot_internal/*` | User Management |
| `https://copilot-telemetry.githubusercontent.com/telemetry` | Telemetry |
| `https://default.exp-tas.com/` | Telemetry |
| `https://copilot-proxy.githubusercontent.com/` | API service for {% data variables.product.prodname_copilot_short %} suggestions |
| `https://origin-tracker.githubusercontent.com` | API service for {% data variables.product.prodname_copilot_short %} suggestions |
| `https://*.githubcopilot.com` | API service for {% data variables.product.prodname_copilot_short %} suggestions |
Additional domains and URLs may require allowlisting, depending on your organization's security policies and the editors in use. For more information about specific editors, see "[Further reading](#further-reading)."
## Further reading
* [Network Connections in {% data variables.product.prodname_vscode %}](https://code.visualstudio.com/docs/setup/network)
* [Install and use Visual Studio and Azure Services behind a firewall or proxy server](https://learn.microsoft.com/en-us/visualstudio/install/install-and-use-visual-studio-behind-a-firewall-or-proxy-server)
* "[AUTOTITLE](/get-started/using-github/troubleshooting-connectivity-problems)"
For an optimal {% data variables.product.prodname_copilot_short %} experience, you should create an "allowlist" that lets certain URLs, ports, and protocols through your firewall. See "[AUTOTITLE](/copilot/managing-copilot/managing-github-copilot-in-your-organization/configuring-your-proxy-server-or-firewall-for-copilot)."

View File

@@ -47,6 +47,8 @@ If there is a problem with your proxy setup, you may see the following error: `{
If you know you are connecting via a proxy, make sure the proxy is configured correctly in your environment. For more information, see "[AUTOTITLE](/copilot/configuring-github-copilot/configuring-network-settings-for-github-copilot#configuring-proxy-settings-for-github-copilot)."
> [!NOTE] If you are an employee of a company with a proxy server, your company must also configure proxy settings for {% data variables.product.prodname_copilot_short %} at the company level. See "[AUTOTITLE](/copilot/managing-copilot/managing-github-copilot-in-your-organization/configuring-your-proxy-server-or-firewall-for-copilot)."
{% data variables.product.prodname_copilot %} uses custom code to connect to proxies. This means a proxy setup supported by your editor is not necessarily supported by {% data variables.product.prodname_copilot %}. Some common causes for errors related to proxies are:
* If your proxy's URL starts `https://`, it is not currently supported by {% data variables.product.prodname_copilot %}.

View File

@@ -34,6 +34,7 @@ The following sections list some of the available keyboard shortcuts, organized
|-----------|------------
|<kbd>S</kbd> or <kbd>/</kbd> | Focus the search bar. For more information, see "[AUTOTITLE](/search-github/getting-started-with-searching-on-github/about-searching-on-github)."
|<kbd>G</kbd> <kbd>N</kbd> | Go to your notifications. For more information, see "[AUTOTITLE](/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/about-notifications)."
|<kbd>Option</kbd>+<kbd>↑</kbd> (Mac) or </br> <kbd>Alt</kbd>+<kbd>↑</kbd> (Windows/Linux) | Move focus from an element to its hovercard |
|<kbd>Esc</kbd> | When focused on a user, issue, or pull request hovercard, closes the hovercard and refocuses on the element the hovercard is in
## Repositories

View File

@@ -16,7 +16,7 @@ featuredLinks:
startHere:
- /github-cli/github-cli/creating-github-cli-extensions
- /github-cli/github-cli/using-github-cli-extensions
- /actions/using-workflows/using-github-cli-in-workflows
- /actions/writing-workflows/choosing-what-your-workflow-does/using-github-cli-in-workflows
- /codespaces/developing-in-a-codespace/using-github-codespaces-with-github-cli
popular:
- /pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request

View File

@@ -4,9 +4,8 @@ getting_started:
Discover the possibilities of {% data variables.product.prodname_actions %}
by creating your first workflow.
guides:
- /actions/learn-github-actions/understanding-github-actions
- /actions/learn-github-actions/finding-and-customizing-actions
- /actions/learn-github-actions/essential-features-of-github-actions
- /actions/about-github-actions/understanding-github-actions
- /actions/writing-workflows/choosing-what-your-workflow-does/finding-and-customizing-actions
- /actions/using-workflows/about-workflows
- /actions/using-workflows/reusing-workflows
- /actions/security-guides/security-hardening-for-github-actions
@@ -20,7 +19,7 @@ adopting_github_actions_for_your_enterprise_ghec:
guides:
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/about-github-actions-for-enterprises
- /actions/learn-github-actions/understanding-github-actions
- /actions/about-github-actions/understanding-github-actions
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/introducing-github-actions-to-your-enterprise
- >-
@@ -40,7 +39,7 @@ adopting_github_actions_for_your_enterprise_ghes:
guides:
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/about-github-actions-for-enterprises
- /actions/learn-github-actions/understanding-github-actions
- /actions/about-github-actions/understanding-github-actions
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/introducing-github-actions-to-your-enterprise
- >-

View File

@@ -43,7 +43,7 @@ adopting_github_actions_for_your_enterprise_ghec:
guides:
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/about-github-actions-for-enterprises
- /actions/learn-github-actions/understanding-github-actions
- /actions/about-github-actions/understanding-github-actions
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/introducing-github-actions-to-your-enterprise
- >-
@@ -63,7 +63,7 @@ adopting_github_actions_for_your_enterprise_ghes:
guides:
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/about-github-actions-for-enterprises
- /actions/learn-github-actions/understanding-github-actions
- /actions/about-github-actions/understanding-github-actions
- >-
/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/introducing-github-actions-to-your-enterprise
- >-

View File

@@ -1,5 +1 @@
{% note %}
**Note:** {% data variables.product.company_short %} may apply a temporary authorization hold for the value of the usage-based costs in advance, which will appear as a pending charge in your account's payment method.
{% endnote %}
>[!NOTE] {% data variables.product.company_short %} may apply a temporary authorization hold for the value of the usage-based costs in advance, which will appear as a pending charge in your account's payment method.

61
package-lock.json generated
View File

@@ -123,6 +123,7 @@
"@types/react-dom": "^18.3.0",
"@types/semver": "^7.5.8",
"@types/tcp-port-used": "1.0.4",
"@types/website-scraper": "^1.2.10",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser": "^7.16.0",
"chalk": "^5.0.1",
@@ -3168,6 +3169,12 @@
"@types/node": "*"
}
},
"node_modules/@types/caseless": {
"version": "0.12.5",
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz",
"integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==",
"dev": true
},
"node_modules/@types/connect": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
@@ -3368,8 +3375,12 @@
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
},
"node_modules/@types/node": {
"version": "18.14.6",
"license": "MIT"
"version": "22.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz",
"integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==",
"dependencies": {
"undici-types": "~6.11.1"
}
},
"node_modules/@types/prop-types": {
"version": "15.7.4",
@@ -3413,6 +3424,32 @@
"@types/react": "*"
}
},
"node_modules/@types/request": {
"version": "2.48.12",
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz",
"integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==",
"dev": true,
"dependencies": {
"@types/caseless": "*",
"@types/node": "*",
"@types/tough-cookie": "*",
"form-data": "^2.5.0"
}
},
"node_modules/@types/request/node_modules/form-data": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
"dev": true,
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 0.12"
}
},
"node_modules/@types/semver": {
"version": "7.5.8",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
@@ -3475,10 +3512,25 @@
"integrity": "sha512-0vQ4fz9TTM4bCdllYWEJ2JHBUXR9xqPtc70dJ7BMRDVfvZyYdrgey3nP5RRcVj+qAgnHJM8r9fvgrfnPMxdnhA==",
"dev": true
},
"node_modules/@types/tough-cookie": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
"integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
"dev": true
},
"node_modules/@types/unist": {
"version": "2.0.6",
"license": "MIT"
},
"node_modules/@types/website-scraper": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/@types/website-scraper/-/website-scraper-1.2.10.tgz",
"integrity": "sha512-yJR4klQv1/7PuqMmgm331re3gQLKHt3dtCYQPPDwlCdthZgE/zHhWyb3XsXCVt6IPnMnOb62I5oJIZECqfvx1A==",
"dev": true,
"dependencies": {
"@types/request": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "7.15.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz",
@@ -14505,6 +14557,11 @@
"node": ">=14.0"
}
},
"node_modules/undici-types": {
"version": "6.11.1",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
"integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ=="
},
"node_modules/unified": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.3.tgz",

View File

@@ -19,7 +19,7 @@
"all-documents": "tsx src/content-render/scripts/all-documents/cli.ts",
"analyze-text": "node src/search/scripts/analyze-text.js",
"analyze-comment": "tsx src/events/scripts/analyze-comment-cli.ts",
"archive-version": "node --max-old-space-size=8192 src/ghes-releases/scripts/archive-version.js",
"archive-version": "tsx --max-old-space-size=16384 src/ghes-releases/scripts/archive-version.ts",
"audit-log-sync": "tsx src/audit-logs/scripts/sync.ts",
"build": "next build",
"check-content-type": "node src/workflows/check-content-type.js",
@@ -58,6 +58,7 @@
"prettier-check": "prettier -c \"**/*.{ts,tsx,js,mjs,scss,yml,yaml}\"",
"prevent-pushes-to-main": "node src/workflows/prevent-pushes-to-main.js",
"release-banner": "node src/ghes-releases/scripts/release-banner.js",
"reusables": "tsx src/content-render/scripts/reusables-cli.ts",
"remove-version-markup": "node src/ghes-releases/scripts/remove-version-markup.js",
"rendered-content-link-checker": "tsx src/links/scripts/rendered-content-link-checker.ts",
"rendered-content-link-checker-cli": "tsx src/links/scripts/rendered-content-link-checker-cli.ts",
@@ -339,6 +340,7 @@
"@types/react-dom": "^18.3.0",
"@types/semver": "^7.5.8",
"@types/tcp-port-used": "1.0.4",
"@types/website-scraper": "^1.2.10",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser": "^7.16.0",
"chalk": "^5.0.1",

View File

@@ -3,5 +3,5 @@
"apiOnlyEvents": "This event is not available in the web interface, only via the REST API, audit log streaming, or JSON/CSV exports.",
"apiRequestEvent": "This event is only available via audit log streaming."
},
"sha": "2ff6ca1490c05079b409af85320cec5089dc388a"
"sha": "0d0a015e748451e1083bdce44ce19206c4cda4d3"
}

View File

@@ -141,7 +141,7 @@ describe.skip('category pages', () => {
}
await contextualize(req as ExtendedRequest, res as Response, next)
await shortVersions(req, res, next)
await shortVersions(req as ExtendedRequest, res as Response, next)
// Save the index title for later testing
indexTitle = data.title.includes('{')

View File

@@ -66,7 +66,7 @@ export async function allDocuments(options: Options): Promise<AllDocument[]> {
}
await contextualize(req as ExtendedRequest, res as Response, next)
await shortVersions(req, res, next)
await shortVersions(req as ExtendedRequest, res as Response, next)
req.context.page = page
features(req as any, res as any, next)

View File

@@ -0,0 +1,71 @@
// Usage: npm run reusables -- --help
// Usage: npm run reusables -- find used accounts/create-account.md
// Usage: npm run reusables -- find unused accounts/create-account.md
// Usage: npm run reusables -- find any-unused
// Usage: npm run reusables -- find top-used
import { Command } from 'commander'
import { findTopUsed, findUsed } from './reusables-cli/find/used'
import { findPotentialUses } from './reusables-cli/find/potential-uses'
import { findUnused } from './reusables-cli/find/unused'
const defaultSimilarityThreshold = 10000
const defaultTopUsedCount = 10
const absolutePathDescription = 'Show absolute paths in output instead of relative path to repo'
const program = new Command()
program
.name('reusables-helper-cli')
.description('Tools to help with reusable Docs content snippets')
const findCommand = program.command('find')
findCommand
.command('used')
.description('Find all content files that use a specific reusable.')
.argument(
'<reusable-path>',
'Path to the reusable file relative to content/data/reusables, e.g. "accounts/create-account.md".',
)
.option('-a --absolute', absolutePathDescription, false)
.action(findUsed)
findCommand
.command('top-used')
.description('Find the top x most used reusables.')
.argument(
'[number-of-most-used-to-find]',
'Number of most used reusables to find.',
defaultTopUsedCount,
)
.option('-a --absolute', absolutePathDescription, false)
.action(findTopUsed)
findCommand
.command('unused')
.description(
'Find all reusables that are not used in any content files. WARNING: This command may take a long time to run.',
)
.option('-a --absolute', absolutePathDescription, false)
.action(findUnused)
findCommand
.command('potential-uses')
.option(
'-s, --similar',
'Find files where contents loosely matches a reusable instead of an exact match.',
)
.option(
'-t, --threshold <number>',
'Similarity threshold for similar reusables. e.g. 10000. This requires the --similar flag and some experimentation to find a useful value.',
parseFloat,
defaultSimilarityThreshold,
)
.option('-a --absolute', absolutePathDescription, false)
.description(
'Find all content files that could use any reusables, but do not. WARNING: This command may take a long time to run.',
)
.action(findPotentialUses)
program.parse()

View File

@@ -0,0 +1,132 @@
# Reusables CLI
Helpful CLI tool for making it easier to work with `data/reusables`.
Helps find where reusables are already used, and where they could be used.
## Usage
`npm run reusables -- --help` to see commands
## Commands:
`npm run reusables --`:
- [find used <reusable-path>](#command-npm-run-reusables-cli----find-used-reusable-path)
- [find top-used [number-of-most-used-to-find]](#command-npm-run-reusables-cli----find-top-used-number-of-most-used-to-find)
- [find unused](#command-npm-run-reusables-cli----find-unused)
- [find potential-uses](#command-npm-run-reusables-cli----find-potential-uses)
### Command: `npm run reusables -- find used <reusable-path>`
Find where a specific reusable is used
#### Example
`npm run reusables -- find used copilot/signup-procedure.md`
```
Searching for content files that use data/reusables/copilot/signup-procedure.md...
Found 2 files that use data/reusables/copilot/signup-procedure.md.
In content/billing/managing-billing-for-github-copilot/managing-your-github-copilot-individual-subscription.md on:
Line 35
In content/copilot/quickstart.md on:
Line 29
```
### Command: `npm run reusables -- find top-used [number-of-most-used-to-find]`
Find top X (default 10) most used reusables and the number of times they are used.
#### Example
`npm run reusables -- find top-used 5`
```
Searching for the top 5 most used reusables...
0/3225 reusables checked...
100/3225 reusables checked...
(etc, etc)
3225/3225 reusables checked...
Top 5 most used reusables:
#1. 318 uses of data/reusables/repositories/navigate-to-repo.md
#2. 286 uses of data/reusables/profile/access_org.md
#3. 212 uses of data/reusables/enterprise-accounts/access-enterprise.md
#4. 193 uses of data/reusables/profile/org_settings.md
#5. 171 uses of data/reusables/actions/action-checkout.md
```
### Command: `npm run reusables -- find unused`
Find which reusables aren't used in any content files.
This will take ~10+ minutes to run locally. You will be updated at each 5% interval.
#### Example
`npm run reusables -- find unused`
```
Searching 6468 files and 3225 reusables...
Progress: 5% done
Progress: 10% done
Progress: 15% done
...
Found 111 unused reusables:
data/reusables/actions/action-labeler.md
data/reusables/actions/actions-audit-events-for-enterprise.md
data/reusables/actions/actions-audit-events-workflow.md
data/reusables/actions/cache-no-org-policy.md
data/reusables/actions/configure-runner-group-access.md
...
```
### Command: `npm run reusables -- find potential-uses`
Find which files that reusables might be used in.
The command does this by searching every `content/` & `data/` file for strings that match every reusable that isn't ignored in `src/content-render/scripts/reusables-cli/ignore-reusables.ts`.
#### Example
`npm run reusables -- find potential-uses`
```
Searching 6468 files for potential reusable use...
0/3225 reusables checked...
100/3225 reusables checked...
(etc, etc)
3223/3225 reusables checked...
Found 13 files that could use reusables.
Reusable data/reusables/actions/action-labeler.md can be used
In content/actions/using-workflows/reusing-workflows.md on:
Line 146
Line 188
(cont.)
```
#### Ignoring reusables
Some reusables might not make sense to "reuse" everywhere they could be reused. For instance, at the time of writing there is a reusable that is just the number "30" which shows up in certain files, but doesn't make sense to be replaced with a reusable.
In these cases you can skip these reusables from being checked by the `find potential-uses` command by adding their paths to the array in [src/content-render/scripts/reusables-cli/ignore-reusables.ts](./ignore-unused-reusables.ts)
#### Similarity search
This may or may not be a useful search. It does a looser search to find places where the reusable _may_ be usable. You can include this type of search with the `-s` flag. You can alter the "threshold" used by the scoring algorithm to show more (higher number) or less (lower number) potential results with the `-t` flag.
The threshold is a number that finds how similar the words in the reusable are to the words in a given article.
A good default threshold number is `15000`. You can experiment with a higher/lower number if you aren't getting good results.
e.g. `npm run reusables -- find potential-uses -s -t 15000`

View File

@@ -0,0 +1,99 @@
import fs from 'fs'
import {
FilesWithLineNumbers,
FilesWithSimilarity,
findIndicesOfSubstringInString,
findSimilarSubStringInString,
getAllContentFilePaths,
getAllReusablesFilePaths,
getRelativeReusablesPath,
printFindsWithLineNumbers,
} from '../shared'
import { reusablesToIgnore } from '../ignore-reusables'
export function findPotentialUses({
similar,
threshold,
absolute,
}: {
similar?: boolean
threshold: number
absolute: boolean
}) {
const reusableFiles = getAllReusablesFilePaths()
const allFilePaths = getAllContentFilePaths()
const filesThatCouldUseReusable: FilesWithLineNumbers = []
const filesThatCouldUseReusableSimilar: FilesWithSimilarity = []
// Read all content & data files into memory
const allFileContents = allFilePaths.map((filePath) => {
return {
filePath,
fileContents: fs.readFileSync(filePath, 'utf-8'),
}
})
console.log(`Searching ${allFileContents.length} files for potential reusable use...`)
if (similar) {
console.log('Using similarity search, this may take a while...')
}
let reusableCount = 0
let reusableContents
for (const reusableFilePath of reusableFiles) {
reusableContents = fs.readFileSync(reusableFilePath, 'utf-8')
const reusableRelativeFilePath = getRelativeReusablesPath(reusableFilePath)
if (!reusableContents.trim()) {
if (!absolute) {
console.log(`Skipping empty reusable file: ${reusableRelativeFilePath}`)
} else {
console.log(`Skipping empty reusable file: ${reusableFilePath}`)
}
continue
}
if (reusablesToIgnore.includes(reusableRelativeFilePath)) {
continue
}
if (reusableCount % 100 === 0) {
console.log(`${reusableCount}/${reusableFiles.length} reusables checked...`)
}
reusableCount += 1
for (const { filePath, fileContents } of allFileContents) {
// Skip the reusable file itself
if (filePath === reusableFilePath) continue
const indices = findIndicesOfSubstringInString(reusableContents.trim(), fileContents)
if (indices.length > 0) {
// Find line numbers of each index in fileContents
const lineNumbers = indices.map((index) => fileContents.slice(0, index).split('\n').length)
filesThatCouldUseReusable.push({
filePath,
lineNumbers,
reusableFile: reusableFilePath,
})
}
if (similar) {
const similarityScore = findSimilarSubStringInString(reusableContents.trim(), fileContents)
if (similarityScore > threshold) {
filesThatCouldUseReusableSimilar.push({
filePath,
similarityScore,
reusableFile: reusableFilePath,
})
}
}
}
}
console.log(`${reusableCount}/${reusableFiles.length} reusables checked...`)
console.log(`\nFound ${filesThatCouldUseReusable.length} files that could use reusables.`)
printFindsWithLineNumbers(absolute, filesThatCouldUseReusable)
}

View File

@@ -0,0 +1,54 @@
import fs from 'fs'
import path from 'path'
import { getLiquidTokens } from '@/content-linter/lib/helpers/liquid-utils.js'
import {
getAllContentFilePaths,
getAllReusablesFilePaths,
getRelativeReusablesPath,
resolveReusablePath,
} from '../shared'
export function findUnused({ absolute }: { absolute: boolean }) {
const reusableFilePaths = getAllReusablesFilePaths()
const allFilePaths = getAllContentFilePaths()
const usedReusables = new Set<string>()
const totalFiles = allFilePaths.length
let lastLoggedPercent = 0
console.log(`Searching ${totalFiles} files and ${reusableFilePaths.length} reusables...`)
for (let i = 0; i < totalFiles; i++) {
const filePath = allFilePaths[i]
const fileContents = fs.readFileSync(filePath, 'utf-8')
const liquidTokens = getLiquidTokens(fileContents)
for (const token of liquidTokens) {
const { args, name } = token
if (name === 'data' && args.startsWith('reusables.')) {
const reusableName = path.join('data', ...args.split('.')) + '.md'
// Special cases where we don't want them to count as reusables. It's an example in a how-to doc
if (reusableName.includes('foo/bar.md') || reusableName.includes('your-reusable-name.md')) {
continue
}
const reusablePath = resolveReusablePath(reusableName)
usedReusables.add(reusablePath)
}
}
const percentDone = Math.floor(((i + 1) / totalFiles) * 100)
if (percentDone >= lastLoggedPercent + 5) {
console.log(`Progress: ${percentDone}% done`)
lastLoggedPercent = percentDone
}
}
const unusedReusables = reusableFilePaths.filter((filePath) => !usedReusables.has(filePath))
console.log(`\nFound ${unusedReusables.length} unused reusables:`)
for (const reusableFilePath of unusedReusables) {
const printReusablePath = absolute
? reusableFilePath
: getRelativeReusablesPath(reusableFilePath)
console.log(printReusablePath)
}
}

View File

@@ -0,0 +1,74 @@
import fs from 'fs'
import path from 'path'
import { getLiquidTokens } from '@/content-linter/lib/helpers/liquid-utils.js'
import {
FilesWithLineNumbers,
getAllContentFilePaths,
getIndicesOfLiquidVariable,
getRelativeReusablesPath,
getReusableLiquidString,
printFindsWithLineNumbers,
resolveReusablePath,
} from '../shared'
export function findUsed(reusablePath: string, { absolute }: { absolute: boolean }) {
const reusableFilePath = resolveReusablePath(reusablePath)
const reusableLiquidVar = getReusableLiquidString(reusableFilePath)
const printReusablePath = absolute ? reusableFilePath : getRelativeReusablesPath(reusableFilePath)
console.log(`Searching for content files that use ${printReusablePath}...`)
const allFilePaths = getAllContentFilePaths()
const filesWithReusables: FilesWithLineNumbers = []
for (const filePath of allFilePaths) {
// Skip the reusable file itself
if (filePath === reusableFilePath) continue
const fileContents = fs.readFileSync(filePath, 'utf-8')
const indices = getIndicesOfLiquidVariable(reusableLiquidVar, fileContents)
if (indices.length > 0) {
// Find line numbers of each index in fileContents
const lineNumbers = indices.map((index) => fileContents.slice(0, index).split('\n').length)
filesWithReusables.push({
filePath,
lineNumbers,
})
}
}
console.log(`\nFound ${filesWithReusables.length} files that use ${printReusablePath}.`)
printFindsWithLineNumbers(absolute, filesWithReusables)
}
export function findTopUsed(numberOfMostUsedToFind: number, { absolute }: { absolute: boolean }) {
const allFilePaths = getAllContentFilePaths()
const reusableCounts = new Map<string, number>()
for (const filePath of allFilePaths) {
const fileContents = fs.readFileSync(filePath, 'utf-8')
const liquidTokens = getLiquidTokens(fileContents)
for (const token of liquidTokens) {
const { args, name } = token
if (name === 'data' && args.startsWith('reusables.')) {
reusableCounts.set(args, (reusableCounts.get(args) || 0) + 1)
}
}
}
const sortedCounts = Array.from(reusableCounts.entries()).sort((a, b) => b[1] - a[1])
console.log(`\nTop ${numberOfMostUsedToFind} most used reusables:`)
let i = 0
for (const [reusable, count] of sortedCounts.slice(0, numberOfMostUsedToFind)) {
let printReusablePath = path.join('data', ...reusable.split('.')) + '.md'
if (absolute) {
printReusablePath = path.resolve(printReusablePath)
}
console.log(`#${`${++i}.`.padEnd(3)} ${count} uses of ${printReusablePath}`)
}
}

View File

@@ -0,0 +1,5 @@
// List of reusables to ignore when checking for potential uses of reusables
// Make sure paths are relative to the root of the repo
export const reusablesToIgnore = [
'data/reusables/copilot/trial-period.md', // Just a number, so it pops up in unrelated files
]

View File

@@ -0,0 +1,196 @@
import walk from 'walk-sync'
import path from 'path'
import { TokenizationError } from 'liquidjs'
import { getLiquidTokens } from '@/content-linter/lib/helpers/liquid-utils'
const __dirname = path.dirname(new URL(import.meta.url).pathname)
const repoRoot = path.resolve(__dirname, '../../../../')
const contentDirectory = path.resolve(__dirname, repoRoot, 'content/')
const dataDirectory = path.resolve(__dirname, repoRoot, 'data/')
const reusablesDirectory = path.resolve(dataDirectory, 'reusables/')
export type FilesWithLineNumbers = {
filePath: string
lineNumbers: number[]
reusableFile?: string
}[]
export type FilesWithSimilarity = {
filePath: string
similarityScore: number
reusableFile?: string
}[]
export function filterFiles(files: string[]) {
return files.filter(
(filePath) =>
filePath.endsWith('.md') || (filePath.endsWith('.yml') && !filePath.endsWith('README.md')),
)
}
export function getAllContentFilePaths() {
const allContentFiles = filterFiles(
walk(contentDirectory, {
includeBasePath: true,
directories: false,
}),
)
const allDataFiles = filterFiles(
walk(dataDirectory, {
includeBasePath: true,
directories: false,
}),
)
return [...allContentFiles, ...allDataFiles]
}
// Get the string that represents the reusable in the content files
export function getReusableLiquidString(reusablePath: string): string {
const relativePath = path.relative(reusablesDirectory, reusablePath)
return `reusables.${relativePath.slice(0, -3).split('/').join('.')}`
}
export function getIndicesOfLiquidVariable(liquidVariable: string, fileContents: string): number[] {
const indices: number[] = []
try {
for (const token of getLiquidTokens(fileContents)) {
if (token.name === 'data' && token.args.trim() === liquidVariable) {
indices.push(token.begin)
}
}
} catch (err) {
if (err instanceof TokenizationError) return []
throw err
}
return indices
}
// Find the path to a reusable file.
export function resolveReusablePath(reusablePath: string): string {
// Try .md if extension is not provided
if (!reusablePath.endsWith('.md') && !reusablePath.endsWith('.yml')) {
reusablePath += '.md'
}
// Allow user to just pass the name of the file. If it's not ambiguous, we'll find it.
const allReusableFiles = getAllReusablesFilePaths()
const foundPaths = []
for (const possiblePath of allReusableFiles) {
if (possiblePath.includes(reusablePath)) {
foundPaths.push(possiblePath)
}
}
if (foundPaths.length === 0) {
console.error(`Reusables file not found: ${reusablePath}`)
process.exit(1)
} else if (foundPaths.length === 1) {
return foundPaths[0]
} else {
console.error(`Multiple reusables found by name: ${reusablePath}`)
for (let i = 0; i < foundPaths.length; i++) {
console.error(` ${i + 1}: ${getRelativeReusablesPath(foundPaths[i])}`)
}
console.error('Please specify which reusable by passing the full path')
process.exit(1)
}
}
export function getAllReusablesFilePaths(): string[] {
return filterFiles(
walk(reusablesDirectory, {
includeBasePath: true,
directories: false,
}),
)
}
export function findIndicesOfSubstringInString(substr: string, str: string): number[] {
str = str.toLowerCase()
const result: number[] = []
let idx = str.indexOf(substr)
while (idx !== -1) {
result.push(idx)
idx = str.indexOf(substr, idx + 1)
}
return result
}
export function findSimilarSubStringInString(substr: string, str: string) {
// Take every sentence in the substr, lower case it, and compare it to every sentence in the str to get a similarity score
const substrSentences = substr.split('.').map((sentence) => sentence.toLowerCase())
const corpus = str.split('.').map((sentence) => sentence.toLowerCase())
let similarityScore = 0
// Find how similar every two strings are based on the words they share
for (const substrSentence of substrSentences) {
for (const sentence of corpus) {
const substrTokens = substrSentence.split(' ')
const tokens = sentence.split(' ')
const sharedWords = substrTokens.filter((token) => tokens.includes(token))
similarityScore += sharedWords.length / (substrTokens.length + tokens.length)
}
}
// Normalize the similarity score
return Math.round((similarityScore / substrSentences.length) * corpus.length)
}
export function printFindsWithLineNumbers(
absolute: boolean,
reusableFindings: { filePath: string; lineNumbers: number[]; reusableFile?: string }[],
similarityFindings?: { filePath: string; similarityScore: number; reusableFile?: string }[],
) {
for (const { filePath, lineNumbers, reusableFile } of reusableFindings) {
let printReusablePath = reusableFile
let printFilePath = filePath
if (!absolute) {
printReusablePath = getRelativeReusablesPath(printReusablePath as string)
printFilePath = path.relative(repoRoot, printFilePath)
}
if (reusableFile) {
console.log(`\nReusable ${printReusablePath} can be used`)
console.log(`In ${printFilePath} on:`)
} else {
console.log(`\nIn ${printFilePath} on:`)
}
for (const lineNumber of lineNumbers) {
console.log(` Line ${lineNumber}`)
}
}
if (similarityFindings?.length) {
console.log('\nFindings using "similar" algorithm:')
for (const { filePath, similarityScore, reusableFile } of similarityFindings) {
let printReusablePath = reusableFile
let printFilePath = filePath
if (!absolute) {
printReusablePath = getRelativeReusablesPath(printReusablePath as string)
printFilePath = path.relative(repoRoot, printFilePath)
}
if (reusableFile) {
console.log(`\nReusables ${printReusablePath} can be used`)
console.log(`In ${printFilePath} with similarity score: ${similarityScore}`)
} else {
console.log(`\nIn ${printFilePath} with similarity score: ${similarityScore}`)
}
}
}
}
export function getRelativeReusablesPath(reusablePath: string) {
if (!reusablePath) {
return ''
}
return path.relative(repoRoot, reusablePath)
}

View File

@@ -15,17 +15,23 @@ import { program } from 'commander'
import { rimraf } from 'rimraf'
import http from 'http'
import createApp from '#src/frame/lib/app.js'
import createApp from '@/frame/lib/app'
import EnterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
import loadRedirects from '#src/redirects/lib/precompile.js'
import { loadPageMap, loadPages } from '#src/frame/lib/page-data.js'
import { languageKeys } from '#src/languages/lib/languages.js'
import { RewriteAssetPathsPlugin } from '@/ghes-releases/scripts/rewrite-asset-paths'
const port = '4001'
const host = `http://localhost:${port}`
const version = EnterpriseServerReleases.oldestSupported
const REMOTE_ENTERPRISE_STORAGE_URL = 'https://githubdocs.azureedge.net/enterprise'
// Once page-data.js is converted to TS,
// we can import the more comprehesive type
type PageList = Array<Object>
type MapObj = { [key: string]: string }
program
.description(
'Scrape HTML of the oldest supported Enterprise version and add it to a temp output directory.',
@@ -57,76 +63,10 @@ const tmpArchivalDirectory = output
: path.join(process.cwd(), `tmpArchivalDir_${version}`)
main()
class RewriteAssetPathsPlugin {
constructor(version, tempDirectory) {
this.version = version
this.tempDirectory = tempDirectory
}
apply(registerAction) {
registerAction('onResourceSaved', async ({ resource }) => {
// Show some activity
process.stdout.write('.')
// Only operate on HTML files
if (!resource.isHtml() && !resource.isCss()) return
// Get the text contents of the resource
const text = resource.getText()
let newBody = text
// Rewrite HTML asset paths. Example:
// ../assets/images/foo/bar.png ->
// https://githubdocs.azureedge.net/github-images/enterprise/2.17/assets/images/foo/bar.png
if (resource.isHtml()) {
// Remove nextjs scripts and manifest.json link
newBody = newBody.replace(
/<script\ssrc="(\.\.\/)*_next\/static\/[\w]+\/(_buildManifest|_ssgManifest).js?".*?><\/script>/g,
'',
)
newBody = newBody.replace(/<link href=".*manifest.json".*?>/g, '')
if (!localDev) {
// Rewrite asset paths
newBody = newBody.replace(
/(?<attribute>src|href)="(?:\.\.\/|\/)*(?<basepath>_next\/static|javascripts|stylesheets|assets\/fonts|assets\/cb-\d+\/images|node_modules)/g,
(match, attribute, basepath) => {
const replaced = `${REMOTE_ENTERPRISE_STORAGE_URL}/${this.version}/${basepath}`
return `${attribute}="${replaced}`
},
)
}
}
// Rewrite CSS asset paths. Example
// url("../assets/fonts/alliance/alliance-no-1-regular.woff") ->
// url("https://githubdocs.azureedge.net/github-images/enterprise/2.20/assets/fonts/alliance/alliance-no-1-regular.woff")
// url(../../../assets/cb-303/images/octicons/search-24.svg) ->
// url(https://githubdocs.azureedge.net/github-images/enterprise/2.20/assets/cb-303/images/octicons/search-24.svg)
if (resource.isCss()) {
if (!localDev) {
newBody = newBody.replace(
/(?<attribute>url)(?<paren>\("|\()(?:\.\.\/)*(?<basepath>_next\/static|assets\/fonts|assets\/images|assets\/cb-\d+\/images)/g,
(match, attribute, paren, basepath) => {
const replaced = `${REMOTE_ENTERPRISE_STORAGE_URL}/${this.version}/${basepath}`
return `${attribute}${paren}${replaced}`
},
)
}
}
const filePath = path.join(this.tempDirectory, resource.getFilename())
await fs.promises.writeFile(filePath, newBody, resource.encoding)
})
}
}
async function main() {
console.log(`Archiving Enterprise version: ${version}`)
let pageList, urls
let pageList: PageList, urls: Array<string>
if (singlePage) {
const pageName = singlePage.trim().startsWith('/') ? singlePage.slice(1) : singlePage
const urls = languageKeys
@@ -160,7 +100,7 @@ async function main() {
await scrape({
urls,
urlFilter: (url) => {
urlFilter: (url: string) => {
// Do not download assets from other hosts like S3 or octodex.github.com
// (this will keep them as remote references in the downloaded pages)
return url.startsWith(`http://localhost:${port}/`)
@@ -168,8 +108,15 @@ async function main() {
directory: tmpArchivalDirectory,
filenameGenerator: 'bySiteStructure',
requestConcurrency: 6,
plugins: [new RewriteAssetPathsPlugin(version, tmpArchivalDirectory)],
}).catch((err) => {
plugins: [
new RewriteAssetPathsPlugin(
version,
tmpArchivalDirectory,
localDev,
REMOTE_ENTERPRISE_STORAGE_URL,
),
],
}).catch((err: Error) => {
console.error('scraping error')
console.error(err)
})
@@ -195,12 +142,14 @@ async function main() {
})
}
async function createRedirectsFile(pageList, outputDirectory) {
async function createRedirectsFile(pageList: PageList, outputDirectory: string) {
console.log('Creating redirects file...')
const redirects = await loadRedirects(pageList)
const redirectsPerVersion = {}
const redirectsPerVersion: MapObj = {}
Object.entries(redirects).forEach(([oldPath, newPath]) => {
const redirectEntries: Array<[string, string]> = Object.entries(redirects)
redirectEntries.forEach(([oldPath, newPath]) => {
// remove any liquid variables that sneak in
oldPath = oldPath.replace('/{{ page.version }}', '').replace('/{{ currentVersion }}', '')
// ignore any old paths that are not in this version

View File

@@ -0,0 +1,74 @@
import fs from 'fs'
import path from 'path'
export class RewriteAssetPathsPlugin {
version: string
tempDirectory: string
localDev: boolean
replaceUrl: string
constructor(version: string, tempDirectory: string, localDev: boolean, replaceUrl: string) {
this.version = version
this.tempDirectory = tempDirectory
this.localDev = localDev
this.replaceUrl = replaceUrl
}
apply(registerAction: Function) {
registerAction('onResourceSaved', async ({ resource }: any) => {
// Show some activity
process.stdout.write('.')
// Only operate on HTML files
if (!resource.isHtml() && !resource.isCss()) return
// Get the text contents of the resource
const text = resource.getText()
let newBody = text
// Rewrite HTML asset paths. Example:
// ../assets/images/foo/bar.png ->
// https://githubdocs.azureedge.net/github-images/enterprise/2.17/assets/images/foo/bar.png
if (resource.isHtml()) {
// Remove nextjs scripts and manifest.json link
newBody = newBody.replace(
/<script\ssrc="(\.\.\/)*_next\/static\/[\w]+\/(_buildManifest|_ssgManifest).js?".*?><\/script>/g,
'',
)
newBody = newBody.replace(/<link href=".*manifest.json".*?>/g, '')
if (!this.localDev) {
// Rewrite asset paths
newBody = newBody.replace(
/(?<attribute>src|href)="(?:\.\.\/|\/)*(?<basepath>_next\/static|javascripts|stylesheets|assets\/fonts|assets\/cb-\d+\/images|node_modules)/g,
(attribute: string, basepath: string) => {
const replaced = `${this.replaceUrl}/${this.version}/${basepath}`
return `${attribute}="${replaced}`
},
)
}
}
// Rewrite CSS asset paths. Example
// url("../assets/fonts/alliance/alliance-no-1-regular.woff") ->
// url("https://githubdocs.azureedge.net/github-images/enterprise/2.20/assets/fonts/alliance/alliance-no-1-regular.woff")
// url(../../../assets/cb-303/images/octicons/search-24.svg) ->
// url(https://githubdocs.azureedge.net/github-images/enterprise/2.20/assets/cb-303/images/octicons/search-24.svg)
if (resource.isCss()) {
if (!this.localDev) {
newBody = newBody.replace(
/(?<attribute>url)(?<paren>\("|\()(?:\.\.\/)*(?<basepath>_next\/static|assets\/fonts|assets\/images|assets\/cb-\d+\/images)/g,
(attribute: string, paren: string, basepath: string) => {
const replaced = `${this.replaceUrl}/${this.version}/${basepath}`
return `${attribute}${paren}${replaced}`
},
)
}
}
const filePath = path.join(this.tempDirectory, resource.getFilename())
await fs.promises.writeFile(filePath, newBody, resource.encoding)
})
}
}

View File

@@ -60,5 +60,5 @@
"2022-11-28"
]
},
"sha": "49254d7d53442739e29ffe74d2615566aa5fc0a5"
"sha": "2a8a2c6f064a6d0c2bff8cb96b43791beb470f07"
}

View File

@@ -31,11 +31,12 @@ export const LearningTrack = ({ track }: Props) => {
<ol className="pl-4 my-3 f4">
{track.guides.map((guide) => (
<li key={guide.href + track.trackName}>
<span className="color-fg-muted mr-2">
<span className="mr-2">
{tObject('guide_types')[guide.page?.type || ''] as string}
</span>
<Link
href={`${guide.href}?learn=${track.trackName}&learnProduct=${track.trackProduct}`}
className="text-underline"
>
{guide.title}
</Link>

Some files were not shown because too many files have changed in this diff Show More