зеркало из https://github.com/github/docs.git
Merge branch 'main' into patch-2
This commit is contained in:
Коммит
521a2f8827
Двоичные данные
assets/images/help/settings/email_services_addresses.png
Двоичные данные
assets/images/help/settings/email_services_addresses.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 14 KiB После Ширина: | Высота: | Размер: 11 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 16 KiB |
Двоичные данные
assets/images/help/settings/email_services_token.png
Двоичные данные
assets/images/help/settings/email_services_token.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 13 KiB |
Двоичные данные
assets/images/help/settings/save_notification_settings.png
Двоичные данные
assets/images/help/settings/save_notification_settings.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 11 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 8.5 KiB |
|
@ -74,8 +74,8 @@ $ ghe-config -l
|
|||
```
|
||||
Allows you to find the uuid of your node in `cluster.conf`.
|
||||
|
||||
``` shell
|
||||
$ ghe-config _hostname_.uuid
|
||||
```shell
|
||||
$ ghe-config <em>HOSTNAME</em>.uuid
|
||||
```
|
||||
|
||||
{% if currentVersion ver_gt "enterprise-server@2.21" %}
|
||||
|
@ -543,8 +543,8 @@ ghe-dpages status
|
|||
```
|
||||
|
||||
To evacuate a {% data variables.product.prodname_pages %} storage service before evacuating a cluster node:
|
||||
``` shell
|
||||
ghe-dpages evacuate pages-server-<uuid>
|
||||
```shell
|
||||
ghe-dpages evacuate pages-server-<em>UUID</em>
|
||||
```
|
||||
|
||||
#### ghe-spokes
|
||||
|
@ -569,16 +569,16 @@ ghe-spokes route
|
|||
|
||||
To evacuate storage services on a cluster node:
|
||||
|
||||
``` shell
|
||||
ghe-spokes server evacuate git-server-<uuid>
|
||||
```shell
|
||||
ghe-spokes server evacuate git-server-<em>UUID</em>
|
||||
```
|
||||
|
||||
#### ghe-storage
|
||||
|
||||
This utility allows you to evacuate all storage services before evacuating a cluster node.
|
||||
|
||||
``` shell
|
||||
ghe-storage evacuate storage-server-<uuid>
|
||||
```shell
|
||||
ghe-storage evacuate storage-server-<em>UUID</em>
|
||||
```
|
||||
|
||||
### Git
|
||||
|
|
|
@ -44,12 +44,6 @@ settings to allow incoming emails](#configuring-dns-and-firewall-settings-to-all
|
|||
- In the **Authentication** dropdown, choose the type of encryption used by your SMTP server.
|
||||
- In the **No-reply email address** field, type the email address to use in the From and To fields for all notification emails.
|
||||
|
||||
{% note %}
|
||||
|
||||
**Note:** If you select the **Send from author** checkbox in a repository’s **Services** email webhook, outbound email for that repository will send from the author and not from the no-reply email address. For more information, see "[About email notifications for pushes to your repository](/github/administering-a-repository/about-email-notifications-for-pushes-to-your-repository)."
|
||||
|
||||
{% endnote %}
|
||||
|
||||
6. If you want to discard all incoming emails that are addressed to the no-reply email address, select **Discard email addressed to the no-reply email address**.
|
||||
![Checkbox to discard emails addressed to the no-reply email address](/assets/images/enterprise/management-console/discard-noreply-emails.png)
|
||||
7. Under **Support**, choose a type of link to offer additional support to your users:
|
||||
|
|
|
@ -10,7 +10,7 @@ versions:
|
|||
|
||||
### About high availability replication for clusters
|
||||
|
||||
You can configure a cluster deployment of {% data variables.product.prodname_ghe_server %} for high availability, where an identical set of passive nodes sync with the nodes in your active cluster. If hardware or software failures affect the datacenter with your active cluster, you can manually fail over to the replica nodes and continue processing user requests without data loss.
|
||||
You can configure a cluster deployment of {% data variables.product.prodname_ghe_server %} for high availability, where an identical set of passive nodes sync with the nodes in your active cluster. If hardware or software failures affect the datacenter with your active cluster, you can manually fail over to the replica nodes and continue processing user requests, minimizing the impact of the outage.
|
||||
|
||||
In high availability mode, each active node syncs regularly with a corresponding passive node. The passive node runs in standby and does not serve applications or process user requests.
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ You can allocate the user licenses included in your {% data variables.product.pr
|
|||
|
||||
If your {% data variables.product.prodname_ghe_server %} license expires, you won't be able to access {% data variables.product.product_location_enterprise %} via a web browser or Git. If needed, you will be able to use command-line utilities to back up all your data. For more information, see "[Configuring backups on your appliance](/enterprise/admin/guides/installation/configuring-backups-on-your-appliance)." If you have any questions about renewing your license, contact {% data variables.contact.contact_enterprise_sales %}.
|
||||
|
||||
### Uploading a new license to {% data variables.product.prodname_ghe_server %}
|
||||
### Uploading a new license to {% data variables.product.prodname_ghe_server %}
|
||||
|
||||
After you purchase a new license or upgrade an existing license from {% data variables.contact.contact_enterprise_sales %}, you must download your new license file, then upload the file to {% data variables.product.prodname_ghe_server %} to unlock your new user licenses.
|
||||
|
||||
|
@ -45,7 +45,9 @@ If you'd like to renew or add user licenses to {% data variables.product.prodnam
|
|||
13. To select your license, click **License file**, or drag your license file onto **License file**.
|
||||
![Upload license file](/assets/images/enterprise/management-console/upload-license.png)
|
||||
14. Click **Upload**.
|
||||
![Begin upgrade](/assets/images/enterprise/management-console/begin-upload.png)
|
||||
![Begin upload](/assets/images/enterprise/management-console/begin-upload.png)
|
||||
|
||||
{% if enterpriseVersion ver_lt "enterprise-server@3.0" %}If the web UI for {% data variables.product.prodname_ghe_server %} doesn't reflect your updated license immediately, see "[Troubleshooting](#troubleshooting)."{% endif %}
|
||||
|
||||
### Viewing license usage
|
||||
|
||||
|
@ -77,3 +79,23 @@ You can download a JSON file from {% data variables.product.prodname_ghe_server
|
|||
![Upload GitHub Enterprise Servers usage link](/assets/images/help/business-accounts/upload-ghe-server-usage-link.png)
|
||||
11. Upload the JSON file you downloaded from {% data variables.product.prodname_ghe_server %}.
|
||||
![Drag and drop or select a file to upload](/assets/images/help/business-accounts/upload-ghe-server-usage-file.png)
|
||||
|
||||
{% if currentVersion ver_lt "enterprise-server@3.0" %}
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
In some scenarios, the web UI for {% data variables.product.prodname_ghe_server %} may not immediately reflect your new license. You can force the system to detect the license by restarting two system services.
|
||||
|
||||
{% data reusables.enterprise_installation.ssh-into-instance %}
|
||||
1. Restart the services for Git authentication and the HTTP server.
|
||||
|
||||
{% warning %}
|
||||
|
||||
**Warning**: Running the following command will result in a few minutes of user-facing downtime for {% data variables.product.prodname_ghe_server %}. Run the command with care.
|
||||
|
||||
{% endwarning %}
|
||||
|
||||
sudo systemctl restart github-gitauth github-unicorn
|
||||
1. After {% data variables.product.prodname_ghe_server %} returns you to a prompt, try accessing {% data variables.product.prodname_ghe_server %} via the command line or web UI again.
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -22,8 +22,10 @@ Push log entries show:
|
|||
|
||||
### Viewing a repository's push logs
|
||||
|
||||
1. Sign into {% data variables.product.prodname_ghe_server %} as a site administrator.
|
||||
1. Navigate to a repository.
|
||||
{% data reusables.enterprise_site_admin_settings.access-settings %}
|
||||
1. In the upper-right corner of the repository's page, click {% octicon "rocket" aria-label="The rocket ship" %}.
|
||||
![Rocketship icon for accessing site admin settings](/assets/images/enterprise/site-admin-settings/access-new-settings.png)
|
||||
{% data reusables.enterprise_site_admin_settings.security-tab %}
|
||||
4. In the left sidebar, click **Push Log**.
|
||||
![Push log tab](/assets/images/enterprise/site-admin-settings/push-log-tab.png)
|
||||
|
@ -31,8 +33,8 @@ Push log entries show:
|
|||
{% if enterpriseServerVersions contains currentVersion %}
|
||||
### Viewing a repository's push logs on the command-line
|
||||
|
||||
1. SSH into your appliance. For more information, see "[Accessing the administrative shell (SSH)](/enterprise/{{ currentVersion }}/admin/guides/installation/accessing-the-administrative-shell-ssh/)."
|
||||
2. In the appropriate Git repository, open the audit log file:
|
||||
{% data reusables.enterprise_installation.ssh-into-instance %}
|
||||
1. In the appropriate Git repository, open the audit log file:
|
||||
```shell
|
||||
ghe-repo <em>owner</em>/<em>repository</em> -c "less audit_log"
|
||||
```
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: About Campus Advisors
|
||||
intro: 'As an instructor or mentor, learn to use {% data variables.product.prodname_dotcom %} at your school with Campus Advisors training and support.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/about-campus-advisors
|
||||
- /github/teaching-and-learning-with-github-education/about-campus-advisors
|
||||
- /articles/about-campus-advisors
|
||||
versions:
|
|
@ -2,6 +2,7 @@
|
|||
title: About Campus Experts
|
||||
intro: 'As a student, learn the skills you need to build your school''s technology community and a real-world portfolio, with {% data variables.product.prodname_dotcom %} Campus Experts training.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/about-campus-experts
|
||||
- /github/teaching-and-learning-with-github-education/about-campus-experts
|
||||
- /articles/about-campus-experts
|
||||
versions:
|
|
@ -2,6 +2,7 @@
|
|||
title: About GitHub Education for educators and researchers
|
||||
intro: '{% data variables.product.prodname_education %} offers a variety of tools to help educators and researchers work more effectively inside and outside of the classroom.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/about-github-education-for-educators-and-researchers
|
||||
- /github/teaching-and-learning-with-github-education/about-github-education-for-educators-and-researchers
|
||||
- /articles/about-github-education-for-educators-and-researchers
|
||||
versions:
|
|
@ -2,6 +2,7 @@
|
|||
title: About GitHub Education for students
|
||||
intro: '{% data variables.product.prodname_education %} offers students real-world experience with free access to various developer tools from {% data variables.product.prodname_dotcom %}''s partners.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/about-github-education-for-students
|
||||
- /github/teaching-and-learning-with-github-education/about-github-education-for-students
|
||||
- /articles/about-github-education-for-students
|
||||
versions:
|
||||
|
@ -12,9 +13,9 @@ Using {% data variables.product.prodname_dotcom %} for your school projects is a
|
|||
|
||||
{% data reusables.education.about-github-education-link %}
|
||||
|
||||
Everyone with a {% data variables.product.prodname_dotcom %} account can collaborate in unlimited public and private repositories with {% data variables.product.prodname_free_user %}. As a student, you can also apply for the {% data variables.product.prodname_student_pack %}, which offers free access to tools and services used by professional developers. For more information, see "[Apply for a student developer pack](/education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack)" and [{% data variables.product.prodname_education %}](https://education.github.com/pack).
|
||||
Everyone with a {% data variables.product.prodname_dotcom %} account can collaborate in unlimited public and private repositories with {% data variables.product.prodname_free_user %}. As a student, you can also apply for the {% data variables.product.prodname_student_pack %}, which offers free access to tools and services used by professional developers. For more information, see "[Apply for a student developer pack](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-a-student-developer-pack)" and [{% data variables.product.prodname_education %}](https://education.github.com/pack).
|
||||
|
||||
If you're a member of a FIRST robotics club, your mentor can apply for an educator discount so your team can collaborate using {% data variables.product.prodname_team %}, which allows unlimited users and private repositories, for free. For more information, see "[Apply for an educator or researcher discount](/education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount)."
|
||||
If you're a member of a FIRST robotics club, your mentor can apply for an educator discount so your team can collaborate using {% data variables.product.prodname_team %}, which allows unlimited users and private repositories, for free. For more information, see "[Apply for an educator or researcher discount](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-an-educator-or-researcher-discount)."
|
||||
|
||||
### Further reading
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
title: About GitHub Education
|
||||
intro: '{% data variables.product.prodname_education %} offers a special free product for schools that want to make the most of {% data variables.product.prodname_dotcom %} for their community and agree to specific program requirements.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/about-github-education
|
||||
- /github/teaching-and-learning-with-github-education/about-github-education
|
||||
- /articles/about-github-education
|
||||
versions:
|
||||
|
@ -20,4 +21,4 @@ Teachers can manage a course on software development with {% data variables.prod
|
|||
|
||||
To learn more about training programs for student leaders and teachers, see "[{% data variables.product.prodname_dotcom %} Campus Experts](https://education.github.com/students/experts)" and "[Campus Advisors](https://education.github.com/teachers/advisors)."
|
||||
|
||||
If you're a student or academic faculty and your school isn't partnered with {% data variables.product.prodname_dotcom %} as a {% data variables.product.prodname_education %} school, then you can still individually apply for discounts to use {% data variables.product.prodname_dotcom %}. For more information, see "[Use {% data variables.product.prodname_dotcom %} for your schoolwork](/education/teach-and-learn-with-github-education/use-github-for-your-schoolwork)" or "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research/)."
|
||||
If you're a student or academic faculty and your school isn't partnered with {% data variables.product.prodname_dotcom %} as a {% data variables.product.prodname_education %} school, then you can still individually apply for discounts to use {% data variables.product.prodname_dotcom %}. For more information, see "[Use {% data variables.product.prodname_dotcom %} for your schoolwork](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-for-your-schoolwork)" or "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-in-your-classroom-and-research/)."
|
|
@ -2,6 +2,7 @@
|
|||
title: Apply for a student developer pack
|
||||
intro: 'As a student, you can apply for the {% data variables.product.prodname_student_pack %}, which includes offers and benefits from {% data variables.product.prodname_dotcom %} partners.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack
|
||||
- /github/teaching-and-learning-with-github-education/applying-for-a-student-developer-pack
|
||||
- /articles/applying-for-a-student-developer-pack
|
||||
versions:
|
||||
|
@ -28,7 +29,7 @@ During your tenure as a student, you may be prompted to periodically re-verify y
|
|||
|
||||
{% endnote %}
|
||||
|
||||
For information about renewing your {% data variables.product.prodname_student_pack %}, see "[Expiration and renewals](/education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack/#expiration-and-renewals)."
|
||||
For information about renewing your {% data variables.product.prodname_student_pack %}, see "[Expiration and renewals](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-a-student-developer-pack/#expiration-and-renewals)."
|
||||
|
||||
### Applying for a {% data variables.product.prodname_student_pack %}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
title: Apply for an educator or researcher discount
|
||||
intro: 'If you''re an educator or a researcher, you can apply to receive {% data variables.product.prodname_team %} for your organization account for free.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount
|
||||
- /github/teaching-and-learning-with-github-education/applying-for-an-educator-or-researcher-discount
|
||||
- /articles/applying-for-a-classroom-discount/
|
||||
- /articles/applying-for-a-discount-for-your-school-club/
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Explore the benefits of teaching and learning with GitHub Education
|
||||
shortTitle: Teach and learn
|
||||
shortTitle: Explore
|
||||
intro: Learn how {% data variables.product.prodname_education %} can benefit your classroom, schoolwork, or research and how to apply for free access to various developer tools from {% data variables.product.company_short %}'s partners.
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education
|
|
@ -3,6 +3,7 @@ title: Use GitHub at your educational institution
|
|||
intro: 'Maximize the benefits of using {% data variables.product.prodname_dotcom %} at your institution for your students, instructors, and IT staff with {% data variables.product.prodname_education %} and our various training programs for students and instructors.'
|
||||
mapTopic: true
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/use-github-at-your-educational-institution
|
||||
- /github/teaching-and-learning-with-github-education/using-github-at-your-educational-institution
|
||||
- /articles/using-github-at-your-educational-institution
|
||||
versions:
|
|
@ -3,6 +3,7 @@ title: Use GitHub for your schoolwork
|
|||
intro: 'As a student, use {% data variables.product.prodname_dotcom %} to collaborate on your school projects and build real-world experience.'
|
||||
mapTopic: true
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/use-github-for-your-schoolwork
|
||||
- /github/teaching-and-learning-with-github-education/using-github-for-your-schoolwork
|
||||
- /articles/using-github-for-your-schoolwork
|
||||
versions:
|
|
@ -3,6 +3,7 @@ title: Use GitHub in your classroom and research
|
|||
intro: 'As an educator or researcher, use {% data variables.product.prodname_dotcom %} to collaborate on your work in a classroom, student or research group, and more.'
|
||||
mapTopic: true
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research
|
||||
- /github/teaching-and-learning-with-github-education/using-github-in-your-classroom-and-research
|
||||
- /articles/using-github-in-your-classroom-and-research
|
||||
versions:
|
|
@ -2,6 +2,7 @@
|
|||
title: Why wasn't my application for a student developer pack approved?
|
||||
intro: 'Review common reasons that applications for the {% data variables.product.prodname_student_pack %} are not approved and learn tips for reapplying successfully.'
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/why-wasnt-my-application-for-a-student-developer-pack-approved
|
||||
- /github/teaching-and-learning-with-github-education/why-wasnt-my-application-for-a-student-developer-pack-approved
|
||||
- /articles/why-was-my-application-for-a-student-developer-pack-denied/
|
||||
- /articles/why-wasn-t-my-application-for-a-student-developer-pack-approved
|
||||
|
@ -64,4 +65,4 @@ Your instructor may still apply for a {% data variables.product.prodname_educati
|
|||
### Further reading
|
||||
|
||||
- "[How to get the GitHub Student Developer Pack without a student ID](https://github.blog/2019-07-30-how-to-get-the-github-student-developer-pack-without-a-student-id/)" on {% data variables.product.prodname_blog %}
|
||||
- "[Apply for a student developer pack](/education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack)"
|
||||
- "[Apply for a student developer pack](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-a-student-developer-pack)"
|
|
@ -2,6 +2,7 @@
|
|||
title: Why wasn't my application for an educator or researcher discount approved?
|
||||
intro: Review common reasons that applications for an educator or researcher discount are not approved and learn tips for reapplying successfully.
|
||||
redirect_from:
|
||||
- /education/teach-and-learn-with-github-education/why-wasnt-my-application-for-an-educator-or-researcher-discount-approved
|
||||
- /github/teaching-and-learning-with-github-education/why-wasnt-my-application-for-an-educator-or-researcher-discount-approved
|
||||
- /articles/why-was-my-application-for-an-educator-or-researcher-discount-denied/
|
||||
- /articles/why-wasn-t-my-application-for-an-educator-or-researcher-discount-approved
|
||||
|
@ -42,4 +43,4 @@ Educators and researchers are not eligible for the partner offers that come with
|
|||
|
||||
### Further reading
|
||||
|
||||
- "[Apply for an educator or researcher discount](/education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount)"
|
||||
- "[Apply for an educator or researcher discount](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-an-educator-or-researcher-discount)"
|
|
@ -12,8 +12,8 @@ Teachers, students, and researchers can use tools from {% data variables.product
|
|||
|
||||
- [Sign up for a new {% data variables.product.prodname_dotcom %} account](/github/getting-started-with-github/signing-up-for-a-new-github-account)
|
||||
- [Git and {% data variables.product.prodname_dotcom %} quickstart ](/github/getting-started-with-github/quickstart)
|
||||
- [Apply for an educator or researcher discount](/education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount)
|
||||
- [Apply for a student developer pack](/education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack)
|
||||
- [Apply for an educator or researcher discount](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-an-educator-or-researcher-discount)
|
||||
- [Apply for a student developer pack](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-a-student-developer-pack)
|
||||
|
||||
### Run a software development course with {% data variables.product.company_short %}
|
||||
|
||||
|
@ -32,7 +32,7 @@ Administer a classroom, assign and review work from your students, and teach the
|
|||
Incorporate {% data variables.product.prodname_dotcom %} into your education, and use the same tools as the professionals.
|
||||
|
||||
- [Git and {% data variables.product.prodname_dotcom %} learning resources](/github/getting-started-with-github/git-and-github-learning-resources)
|
||||
- [Use {% data variables.product.prodname_dotcom %} for your schoolwork](/education/teach-and-learn-with-github-education/use-github-for-your-schoolwork)
|
||||
- [Use {% data variables.product.prodname_dotcom %} for your schoolwork](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-for-your-schoolwork)
|
||||
- [Try {% data variables.product.prodname_desktop %}](/desktop)
|
||||
- [Try {% data variables.product.prodname_cli %}](/github/getting-started-with-github/github-cli)
|
||||
|
||||
|
@ -41,5 +41,5 @@ Incorporate {% data variables.product.prodname_dotcom %} into your education, an
|
|||
Participate in the community, get training from {% data variables.product.company_short %}, and learn or teach new skills.
|
||||
|
||||
- [{% data variables.product.prodname_education_community %}](https://education.github.community)
|
||||
- [About Campus Experts](/education/teach-and-learn-with-github-education/about-campus-experts)
|
||||
- [About Campus Advisors](/education/teach-and-learn-with-github-education/about-campus-advisors)
|
||||
- [About Campus Experts](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/about-campus-experts)
|
||||
- [About Campus Advisors](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/about-campus-advisors)
|
||||
|
|
|
@ -6,16 +6,16 @@ introLinks:
|
|||
quickstart: /education/quickstart
|
||||
featuredLinks:
|
||||
guides:
|
||||
- /education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack
|
||||
- /education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount
|
||||
- /education/teach-and-learn-with-github-education/use-github-at-your-educational-institution
|
||||
- /education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-a-student-developer-pack
|
||||
- /education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-an-educator-or-researcher-discount
|
||||
- /education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-at-your-educational-institution
|
||||
guideCards:
|
||||
- /github/getting-started-with-github/signing-up-for-a-new-github-account
|
||||
- /github/getting-started-with-github/git-and-github-learning-resources
|
||||
- /education/manage-coursework-with-github-classroom/basics-of-setting-up-github-classroom
|
||||
popular:
|
||||
- /education/teach-and-learn-with-github-education/use-github-for-your-schoolwork
|
||||
- /education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research
|
||||
- /education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-for-your-schoolwork
|
||||
- /education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-in-your-classroom-and-research
|
||||
- /desktop
|
||||
- /github/getting-started-with-github/github-cli
|
||||
- /education/manage-coursework-with-github-classroom/teach-with-github-classroom
|
||||
|
@ -39,5 +39,5 @@ versions:
|
|||
free-pro-team: '*'
|
||||
---
|
||||
|
||||
<!-- {% link_with_intro /teach-and-learn-with-github-education %} -->
|
||||
<!-- {% link_with_intro /explore-the-benefits-of-teaching-and-learning-with-github-education %} -->
|
||||
<!-- {% link_with_intro /manage-coursework-with-github-classroom %} -->
|
||||
|
|
|
@ -30,4 +30,4 @@ For more information about teaching with {% data variables.product.prodname_clas
|
|||
|
||||
### Further reading
|
||||
|
||||
- "[Teach and learn with {% data variables.product.prodname_education %}](/education/teach-and-learn-with-github-education)"
|
||||
- "[Explore the benefits of teaching and learning with {% data variables.product.prodname_education %}](/education/teach-and-learn-with-github-education)"
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
---
|
||||
title: Configure default settings for assignment repositories
|
||||
shortTitle: Configure defaults for assignment repositories
|
||||
intro: You can use the Probot Settings app to configure the default settings for repositories that {% data variables.product.prodname_classroom %} creates for an assignment.
|
||||
permissions: Organization owners can configure default settings for assignment repositories by installing a {% data variables.product.prodname_github_app %} for the organization.
|
||||
versions:
|
||||
free-pro-team: '*'
|
||||
redirect_from:
|
||||
- /education/manage-coursework-with-github-classroom/probot-settings
|
||||
---
|
||||
|
||||
### About configuration of defaults for assignment repositories
|
||||
|
||||
{% data variables.product.prodname_classroom %} creates a repository that belongs for each student or team that accepts an assignment. The repository belongs to the organization that you use for {% data variables.product.prodname_classroom %}. Assignment repositories can be empty, or you can use a template repository. For more information, see "[Create an assignment from a template repository](/education/manage-coursework-with-github-classroom/create-an-assignment-from-a-template-repository)."
|
||||
|
||||
{% data reusables.classroom.you-may-want-to-predefine-repository-settings %}
|
||||
|
||||
With the Probot Settings app, you can create a file named _.github/settings.yml_ in a repository that contains a list of settings for the repository, and then install a {% data variables.product.prodname_github_app %} for your organization that automatically applies the settings to the repository.
|
||||
|
||||
You can include _.github/settings.yml_ in a template repository that you use for an assignment in {% data variables.product.prodname_classroom %}. When an individual or team accepts the assignment, {% data variables.product.prodname_classroom %} creates the assignment repository, and the Settings app automatically applies the settings from _.github/settings.yml_.
|
||||
|
||||
Probot is a a project, framework, and collection of free apps to automate {% data variables.product.product_name %}. A Probot app can listen to repository events, like the creation of new commits, comments, and issues, and automatically respond to the event.
|
||||
|
||||
For more information, see the [Probot website](https://probot.github.io) and the [Settings app website](https://probot.github.io/apps/settings/). For more information about {% data variables.product.prodname_github_apps %}, see "[About apps](/developers/apps/about-apps)."
|
||||
|
||||
### Adding the Settings app to your organization
|
||||
|
||||
After you install the Probot Settings app for your organization, the app will apply the settings that you define in _.github/settings.yml_ for any repository in your organization, including new assignment repositories that {% data variables.product.prodname_classroom %} creates.
|
||||
|
||||
1. Navigate to the [Settings app page](https://github.com/apps/settings).
|
||||
1. Click **Install**, then click the organization that you use for {% data variables.product.prodname_classroom %}. Provide the app full access to all repositories owned by the organization.
|
||||
![Installing the Probot Settings app](/assets/images/help/classroom/probot-settings.gif)
|
||||
|
||||
### Configuring default settings for an assignment repository
|
||||
|
||||
1. Create a template repository that contains a _.github/settings.yml_ file. For a complete list of settings, see the [README](https://github.com/probot/settings#github-settings) for the `probot/settings` repository. For more information about using a template repository for starter code in {% data variables.product.prodname_classroom %}, see "[Create an assignment from a template repository](/education/manage-coursework-with-github-classroom/create-an-assignment-from-a-template-repository)."
|
||||
|
||||
{% warning %}
|
||||
|
||||
**Warning:** Do not define `collaborators` in the _.github/settings.yml_ file for your template repository. {% data variables.product.prodname_classroom %} automatically grants teachers and teaching assistants access to assignment repositories.
|
||||
|
||||
{% endwarning %}
|
||||
|
||||
1. Create an assignment using the template repository containing _.github/settings.yml_ as the starter code. {% data reusables.classroom.for-more-information-about-assignment-creation %}
|
||||
|
||||
The Probot Settings app for your organization will now apply the settings you define in _.github/settings.yml_ within the template repository to every assignment repository that {% data reusables.classroom.you-may-want-to-predefine-repository-settings %} creates for a student or team.
|
||||
|
||||
### Further reading
|
||||
|
||||
- [Probot apps](https://probot.github.io/apps/)
|
||||
- [Probot documentation](https://probot.github.io/docs/)
|
|
@ -140,6 +140,6 @@ You can see the teams that are working on or have submitted an assignment in the
|
|||
|
||||
### Further reading
|
||||
|
||||
- "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research)"
|
||||
- "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-in-your-classroom-and-research)"
|
||||
- "[Connect a learning management system to {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/connect-a-learning-management-system-to-github-classroom)"
|
||||
- [Using Existing Teams in Group Assignments?](https://education.github.community/t/using-existing-teams-in-group-assignments/6999) in the {% data variables.product.prodname_education %} Community
|
||||
|
|
|
@ -11,8 +11,6 @@ You can use a template repository on {% data variables.product.product_name %} a
|
|||
|
||||
To use the template repository for your assignment, the template repository must be owned by your organization, or the visibility of the template repository must be public.
|
||||
|
||||
{% data reusables.classroom.you-may-want-to-predefine-repository-settings %} For more information, see "[Configure default settings for assignment repositories](/education/manage-coursework-with-github-classroom/configure-default-settings-for-assignment-repositories)."
|
||||
|
||||
### Further reading
|
||||
|
||||
- "[Create an individual assignment](/education/manage-coursework-with-github-classroom/create-an-individual-assignment)"
|
||||
|
|
|
@ -120,5 +120,5 @@ You can see whether a student has joined the classroom and accepted or submitted
|
|||
|
||||
### Further reading
|
||||
|
||||
- "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research)"
|
||||
- "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-in-your-classroom-and-research)"
|
||||
- "[Connect a learning management system to {% data variables.product.prodname_classroom %}](/education/manage-coursework-with-github-classroom/connect-a-learning-management-system-to-github-classroom)"
|
||||
|
|
|
@ -19,7 +19,6 @@ versions:
|
|||
{% link_in_list /create-an-assignment-from-a-template-repository %}
|
||||
{% link_in_list /leave-feedback-with-pull-requests %}
|
||||
{% link_in_list /use-autograding %}
|
||||
{% link_in_list /configure-default-settings-for-assignment-repositories %}
|
||||
{% link_in_list /connect-a-learning-management-system-to-github-classroom %}
|
||||
|
||||
{% topic_link_in_list /integrate-github-classroom-with-an-ide %}
|
||||
|
|
|
@ -4,5 +4,8 @@ intro: Learn how to set up your classroom and assignments.
|
|||
mapTopic: true
|
||||
versions:
|
||||
free-pro-team: '*'
|
||||
redirect_from:
|
||||
- /education/manage-coursework-with-github-classroom/configure-default-settings-for-assignment-repositories
|
||||
- /education/manage-coursework-with-github-classroom/probot-settings
|
||||
---
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ You can filter email notifications you receive for pushes to a repository. For m
|
|||
{% data reusables.repositories.sidebar-notifications %}
|
||||
5. Type up to two email addresses, separated by whitespace, where you'd like notifications to be sent. If you'd like to send emails to more than two accounts, set one of the email addresses to a group email address.
|
||||
![Email address textbox](/assets/images/help/settings/email_services_addresses.png)
|
||||
6. If you operate your own server, you can verify the integrity of emails via the **Secret** token. This token is sent with the email as the `Approved` header. If the `Approved` header matches the token you sent, you can trust that the email is from {% data variables.product.product_name %}.
|
||||
![Email secret textbox](/assets/images/help/settings/email_services_token.png)
|
||||
7. Click **Save settings**.
|
||||
![Save settings button](/assets/images/help/settings/save_notification_settings.png)
|
||||
1. If you operate your own server, you can verify the integrity of emails via the **Approved header**. The **Approved header** is a token or secret that you type in this field, and that is sent with the email. If the `Approved` header of an email matches the token, you can trust that the email is from {% data variables.product.product_name %}.
|
||||
![Email approved header textbox](/assets/images/help/settings/email_services_approved_header.png)
|
||||
7. Click **Setup notifications**.
|
||||
![Setup notifications button](/assets/images/help/settings/setup_notifications_settings.png)
|
||||
|
||||
### Further reading
|
||||
{% if currentVersion == "free-pro-team@latest" or currentVersion == "github-ae@latest" or currentVersion ver_gt "enterprise-server@2.20" %}
|
||||
|
|
|
@ -22,3 +22,15 @@ If you rename a branch, {% data variables.product.prodname_dotcom %} will automa
|
|||
![Text field for typing new branch name](/assets/images/help/branch/branch-rename-type.png)
|
||||
1. Review the information about local environments, then click **Rename branch**.
|
||||
![Local environment information and "Rename branch" button](/assets/images/help/branch/branch-rename-rename.png)
|
||||
|
||||
### Updating a local clone after a branch name changes
|
||||
|
||||
After you rename a branch in a repository on {% data variables.product.product_name %}, any collaborator with a local clone of the repository will need to update the clone.
|
||||
|
||||
From the local clone of the repository on a computer, run the following commands to update the name of the default branch.
|
||||
|
||||
```shell
|
||||
$ git branch -m <em>OLD-BRANCH-NAME</em> <em>NEW-BRANCH-NAME</em>
|
||||
$ git fetch origin
|
||||
$ git branch -u origin/<em>NEW-DEFAULT-BRANCH-NAME</em> <em>NEW-DEFAULT-BRANCH-NAME</em>
|
||||
```
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: About authentication with SAML single sign-on
|
||||
intro: 'You can access {% if currentVersion == "github-ae@latest" %}{% data variables.product.product_location %}{% elsif currentVersion == "free-pro-team@latest" %}an organization that uses SAML single sign-on (SSO){% endif %} by authenticating {% if currentVersion == "github-ae@latest" %}with SAML single sign-on (SSO) {% endif %}through an identity provider (IdP).{% if currentVersion == "free-pro-team@latest" %}To authenticate with the API or Git on the command line when an organization enforces SAML SSO, you must authorize your personal access token or SSH key.{% endif %}'
|
||||
intro: 'You can access {% if currentVersion == "github-ae@latest" %}{% data variables.product.product_location %}{% elsif currentVersion == "free-pro-team@latest" %}an organization that uses SAML single sign-on (SSO){% endif %} by authenticating {% if currentVersion == "github-ae@latest" %}with SAML single sign-on (SSO) {% endif %}through an identity provider (IdP).{% if currentVersion == "free-pro-team@latest" %} After you authenticate with the IdP successfully from {% data variables.product.product_name %}, you must authorize any personal access token, SSH key, or {% data variables.product.prodname_oauth_app %} you would like to access the organization''s resources.{% endif %}'
|
||||
product: '{% data reusables.gated-features.saml-sso %}'
|
||||
redirect_from:
|
||||
- /articles/about-authentication-with-saml-single-sign-on
|
||||
|
@ -9,6 +9,8 @@ versions:
|
|||
github-ae: '*'
|
||||
---
|
||||
|
||||
### About authentication with SAML SSO
|
||||
|
||||
{% if currentVersion == "github-ae@latest" %}
|
||||
|
||||
SAML SSO allows an enterprise owner to centrally control and secure access to {% data variables.product.product_name %} from a SAML IdP. When you visit {% data variables.product.product_location %} in a browser, {% data variables.product.product_name %} will redirect you to your IdP to authenticate. After you successfully authenticate with an account on the IdP, the IdP redirects you back to {% data variables.product.product_location %}. {% data variables.product.product_name %} validates the response from your IdP, then grants access.
|
||||
|
@ -31,13 +33,17 @@ If you have recently authenticated with your organization's SAML IdP in your bro
|
|||
|
||||
{% data reusables.saml.you-must-periodically-authenticate %}
|
||||
|
||||
To use the API or Git on the command line to access protected content in an organization that uses SAML SSO, you will need to use an authorized personal access token over HTTPS or an authorized SSH key. {% data variables.product.prodname_oauth_app %} access tokens are authorized by default.
|
||||
To use the API or Git on the command line to access protected content in an organization that uses SAML SSO, you will need to use an authorized personal access token over HTTPS or an authorized SSH key.
|
||||
|
||||
If you don't have a personal access token or an SSH key, you can create a personal access token for the command line or generate a new SSH key. For more information, see "[Creating a personal access token](/github/authenticating-to-github/creating-a-personal-access-token)" or "[Generating a new SSH key and adding it to the ssh-agent](/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)."
|
||||
|
||||
To use a new or existing personal access token or SSH key with an organization that enforces SAML SSO, you will need to authorize the token or authorize the SSH key for use with a SAML SSO organization. For more information, see "[Authorizing a personal access token for use with SAML single sign-on](/articles/authorizing-a-personal-access-token-for-use-with-saml-single-sign-on)" or "[Authorizing an SSH key for use with SAML single sign-on](/articles/authorizing-an-ssh-key-for-use-with-saml-single-sign-on)."
|
||||
To use a new or existing personal access token or SSH key with an organization that uses or enforces SAML SSO, you will need to authorize the token or authorize the SSH key for use with a SAML SSO organization. For more information, see "[Authorizing a personal access token for use with SAML single sign-on](/articles/authorizing-a-personal-access-token-for-use-with-saml-single-sign-on)" or "[Authorizing an SSH key for use with SAML single sign-on](/articles/authorizing-an-ssh-key-for-use-with-saml-single-sign-on)."
|
||||
|
||||
You must have an active SAML session each time you authorize an {% data variables.product.prodname_oauth_app %}.
|
||||
### About {% data variables.product.prodname_oauth_apps %} and SAML SSO
|
||||
|
||||
You must have an active SAML session each time you authorize an {% data variables.product.prodname_oauth_app %} to access an organization that uses or enforces SAML SSO.
|
||||
|
||||
After an enterprise or organization owner enables or enforces SAML SSO for an organization, you must reauthorize any {% data variables.product.prodname_oauth_app %} that you previously authorized to access the organization. To see the {% data variables.product.prodname_oauth_apps %} you've authorized or reauthorize an {% data variables.product.prodname_oauth_app %}, visit your [{% data variables.product.prodname_oauth_apps %} page](https://github.com/settings/applications).
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ versions:
|
|||
|
||||
### Discounts for personal accounts
|
||||
|
||||
In addition to the unlimited public and private repositories for students and faculty with {% data variables.product.prodname_free_user %}, verified students can apply for the {% data variables.product.prodname_student_pack %} to receive additional benefits from {% data variables.product.prodname_dotcom %} partners. For more information, see "[Apply for a student developer pack](/education/teach-and-learn-with-github-education/apply-for-a-student-developer-pack)."
|
||||
In addition to the unlimited public and private repositories for students and faculty with {% data variables.product.prodname_free_user %}, verified students can apply for the {% data variables.product.prodname_student_pack %} to receive additional benefits from {% data variables.product.prodname_dotcom %} partners. For more information, see "[Apply for a student developer pack](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-a-student-developer-pack)."
|
||||
|
||||
### Discounts for schools and universities
|
||||
|
||||
Verified academic faculty can apply for {% data variables.product.prodname_team %} for teaching or academic research. For more information, see "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/teach-and-learn-with-github-education/use-github-in-your-classroom-and-research)." You can also request educational materials goodies for your students. For more information, visit [{% data variables.product.prodname_education %}](https://education.github.com/).
|
||||
Verified academic faculty can apply for {% data variables.product.prodname_team %} for teaching or academic research. For more information, see "[Use {% data variables.product.prodname_dotcom %} in your classroom and research](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/use-github-in-your-classroom-and-research)." You can also request educational materials goodies for your students. For more information, visit [{% data variables.product.prodname_education %}](https://education.github.com/).
|
||||
|
||||
### Discounts for nonprofits and libraries
|
||||
|
||||
|
|
|
@ -1,17 +1,5 @@
|
|||
# Search
|
||||
|
||||
## Table of contents
|
||||
- [Overview](#overview)
|
||||
- [Production deploys](#production-deploys)
|
||||
- [Manual sync from a checkout](#manual-sync-from-a-checkout)
|
||||
- [Build without sync (dry run)](#build-without-sync-dry-run)
|
||||
- [Build and sync](#build-and-sync)
|
||||
- [Label-triggered Actions workflow](#label-triggered-actions-workflow)
|
||||
- [Files](#files)
|
||||
- [GitHub Actions workflow files](#github-actions-workflow-files)
|
||||
- [Code files](#code-files)
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
This site's search functionality is powered by [Algolia](https://www.algolia.com), a third-party service.
|
||||
|
@ -24,6 +12,12 @@ To see all existing search-related issues and pull requests, visit [github.com/g
|
|||
|
||||
---
|
||||
|
||||
## How to search
|
||||
|
||||
The site search is part of every version of docs.github.com. On any page, you can use the search box to search the documents we've indexed.
|
||||
You can also query our search endpoint directly at: https://docs.github.com/search?language=en&version=dotcom&query=jekyll
|
||||
This endpoint responds in JSON format, and fronts Algolia and Lunr. We recommend using this endpoint over directly integrating with Algolia or Lunr, as the endpoint will be more stable.
|
||||
|
||||
## Production deploys
|
||||
|
||||
A [GitHub Actions workflow](.github/workflows/sync-algolia-search-indices.yml) triggered by pushes to the `main` branch syncs the search data to Algolia. This process generates structured data for all pages on the site, compares that data to what's currently on Algolia, then adds, updates, or removes indices based on the diff of the local and remote data, being careful not to create duplicate records and avoiding any unnecessary (and costly) indexing operations.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
You may want to predefine the default settings for the assignment repositories that {% data variables.product.prodname_classroom %} creates from a template repository. For example, you may want to disable issues, define labels for pull requests, or protect a branch in some or all of the repositories.
|
|
@ -1 +1 @@
|
|||
Before applying for an individual discount, check if your learning community is already partnered with us as a {% data variables.product.prodname_education %} school. For more information, see "[About {% data variables.product.prodname_education %}](/education/teach-and-learn-with-github-education/about-github-education)."
|
||||
Before applying for an individual discount, check if your learning community is already partnered with us as a {% data variables.product.prodname_education %} school. For more information, see "[About {% data variables.product.prodname_education %}](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/about-github-education)."
|
||||
|
|
|
@ -1 +1 @@
|
|||
- Apply for free [{% data variables.product.prodname_team %}](/articles/github-s-products), which allows unlimited users and private repositories. For more information, see "[Apply for an educator or researcher discount](/education/teach-and-learn-with-github-education/apply-for-an-educator-or-researcher-discount)."
|
||||
- Apply for free [{% data variables.product.prodname_team %}](/articles/github-s-products), which allows unlimited users and private repositories. For more information, see "[Apply for an educator or researcher discount](/education/explore-the-benefits-of-teaching-and-learning-with-github-education/apply-for-an-educator-or-researcher-discount)."
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
1. SSH into {% data variables.product.product_location %}.
|
||||
1. SSH into {% data variables.product.product_location %}. For more information, see "[Accessing the administrative shell (SSH)](/admin/configuration/accessing-the-administrative-shell-ssh)."
|
||||
```shell
|
||||
$ ssh -p 122 admin@<em>HOSTNAME</em>
|
||||
```
|
||||
|
|
|
@ -78,6 +78,7 @@ prodname_marketplace: 'GitHub Marketplace'
|
|||
prodname_github_app: 'GitHub App'
|
||||
prodname_github_apps: 'GitHub Apps'
|
||||
prodname_oauth_app: 'OAuth App'
|
||||
prodname_oauth_apps: 'OAuth Apps'
|
||||
|
||||
# API and developer docs
|
||||
prodname_enterprise_api: 'the {% if enterpriseServerVersions contains currentVersion %}GitHub Enterprise Server{% elsif currentVersion == "github-ae@latest" %}GitHub AE{% endif %} APIs'
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
# Redirects
|
||||
|
||||
Docs redirects are complex! Some reasons why:
|
||||
|
||||
* Docs URLs have changed many times over the years, whether because docs team members have renamed individual articles or made global changes (e.g., moving all `/articles` to `/github`).
|
||||
* Redirects can be hardcoded in frontmatter or generated via code in this directory (or both!).
|
||||
* Live docs and archived docs require different redirect handling because they may have differently formatted URLs (e.g., legacy `/enterprise/2.17` vs. modern `/enterprise-server@2.22`).
|
||||
|
||||
Read on for more about how redirects work under the hood.
|
||||
|
||||
## Precompiled redirects
|
||||
|
||||
Precompiled redirects account for the majority of the docs site's redirect handling.
|
||||
|
||||
When [`lib/warm-server.js`](lib/warm-server.js) runs on server start, it creates all pages in the site by instantiating the [`Page` class](lib/page.js) for each content file, then passes the pages to `lib/redirects/precompile.js` to create redirects. The precompile script runs `lib/redirects/permalinks.js`, which:
|
||||
|
||||
1. Loops over each page's [permalinks](contributing/permalinks.md) and creates an array of legacy paths for each one (via `lib/redirects/get-old-paths-from-permalink.js`). For example, a permalink that starts with `/en/enterprise-server@2.22` results in an array that includes `/en/enterprise/2.22`, `/enterprise/2.22`, etc.
|
||||
2. Loops over each page's [frontmatter `redirect_from` entries](content/README.md#redirect_from) and creates an array of legacy paths for each one (using the same handling as for permalinks).
|
||||
|
||||
The results comprise the `page.redirects` object, where the **keys are legacy paths** and the **values are current permalinks**.
|
||||
|
||||
Additionally, a [static JSON file](lib/redirects/static/developer.json) gets `require`d that contains keys with legacy developer.github.com paths (e.g., `/v4/object/app`) and values with new docs.github.com paths (e.g., `/graphql/reference/objects#app`).
|
||||
|
||||
All of the above are merged into a global redirects object. This object gets added to `req.context` via `middleware/context.js` and is made accessible on every request.
|
||||
|
||||
Because the redirects are precompiled via `warm-server`, that means `middleware/redirects/handle-redirects.js` just needs to do a simple lookup of the requested path in the redirects object.
|
||||
|
||||
### Archived Enterprise redirects
|
||||
|
||||
Archived Enterprise redirects account for a much smaller percentage of redirects on the docs site.
|
||||
|
||||
Some background on archival: a snapshot of the HTML files for each deprecated Enterprise Server version is archived in a separate repo and proxied to docs.github.com via `middleware/archived-enterprise-versions.js`.
|
||||
|
||||
Starting with Enterprise Server 2.18, we updated the archival process to start preserving frontmatter and permalink redirects. But these redirects for 2.13 to 2.17 are not recoverable.
|
||||
|
||||
As a workaround for these lost redirects, we have two files in `lib/redirects/static`:
|
||||
|
||||
* `archived-redirects-from-213-to-217.json`
|
||||
|
||||
This file contains keys equal to old routes and values equal to new routes (aka snapshots of permalinks at the time) for versions 2.13 to 2.17. (The old routes were generated via `lib/redirects/get-old-paths-from-permalink.js`.)
|
||||
|
||||
* `archived-frontmatter-fallbacks.json`
|
||||
|
||||
This file contains an array of arrays, where the child arrays are a group of all frontmatter redirects for each content file. This is essentially list of all the historical paths for the articles in old versions. The problem is, we don't know which historical paths correspond to which versions.
|
||||
|
||||
Here's how the `middleware/archived-enterprise-versions.js` fallback works: if someone tries to access an article that was updated via a now-lost frontmatter redirect (for example, an article at the path `/en/enterprise/2.15/user/articles/viewing-contributions-on-your-profile-page`), the middleware will first look for a redirect in `archived-redirects-from-213-to-217.json`. If it does not find one, it will look for a child array in `archived-frontmatter-fallbacks.json` that contains the requested path. If it finds a relevant array, it will try accessing all the other paths in the array until it finds one that returns a 200. For this example, it would successfully reach `/en/enterprise/2.15/user/articles/viewing-contributions-on-your-profile` (no `-page`).
|
||||
|
||||
This is admittedly an inefficient brute-force approach. But requests for archived docs <2.18 are getting less and less common as organizations upgrade their Enterprise instances, and all the expensive calculation happens in the middleware on page request, not on server warmup, so at least it's a relatively isolated process.
|
||||
|
||||
## Tests
|
||||
|
||||
Redirect tests are mainly found in `tests/routing/*`, with some additional tests in `tests/rendering/server.js`.
|
||||
|
||||
The `tests/fixtures/*` directory includes `developer-redirects.json`, `graphql-redirects.json`, and `rest-redirects.json`.
|
|
@ -1,90 +0,0 @@
|
|||
const path = require('path')
|
||||
const patterns = require('../patterns')
|
||||
const { latest } = require('../enterprise-server-releases')
|
||||
const { getPathWithoutLanguage, getPathWithoutVersion } = require('../path-utils')
|
||||
|
||||
// This function takes a known pre-migration path from developer.github.com and
|
||||
// infers and returns a current, correct docs.github.com path.
|
||||
module.exports = function getDocsPathFromDeveloperPath (oldDeveloperPath, allRedirects, pageMap) {
|
||||
let newPath = oldDeveloperPath
|
||||
|
||||
// Look up the old path in the redirects object BEFORE modifying /v3 and /v4 paths
|
||||
// in case there is a frontmatter redirect.
|
||||
// e.g. /v3/activity/event_types -> /en/developers/webhooks-and-events/github-event-types
|
||||
newPath = allRedirects[newPath] || newPath
|
||||
|
||||
// oneoff redirect
|
||||
const v3OrgPreReceiveHooks = '/v3/orgs/pre_receive_hooks'
|
||||
if (newPath.endsWith(v3OrgPreReceiveHooks)) {
|
||||
newPath = newPath.replace(v3OrgPreReceiveHooks, '/v3/enterprise-admin/organization_pre_receive_hooks')
|
||||
}
|
||||
|
||||
// oneoff redirect
|
||||
const v3RepoPreReceiveHooks = '/v3/repos/pre_receive_hooks'
|
||||
if (newPath.endsWith(v3RepoPreReceiveHooks)) {
|
||||
newPath = newPath.replace(v3RepoPreReceiveHooks, '/v3/enterprise-admin/repository_pre_receive_hooks')
|
||||
}
|
||||
|
||||
// oneoff redirect
|
||||
const v3OrgHooks = '/v3/orgs/hooks'
|
||||
if (newPath.endsWith(v3OrgHooks)) {
|
||||
newPath = newPath.replace(v3OrgHooks, '/v3/orgs/webhooks')
|
||||
}
|
||||
|
||||
// oneoff redirect
|
||||
const v3RepoHooks = '/v3/repos/hooks'
|
||||
if (newPath.endsWith(v3RepoHooks)) {
|
||||
newPath = newPath.replace(v3RepoHooks, '/v3/repos/webhooks')
|
||||
}
|
||||
|
||||
// oneoff redirect for a dotcom developer path to Enterprise-only path on docs.github.com
|
||||
const oauthAuthorizations = '/v3/oauth_authorizations'
|
||||
if (newPath.endsWith(oauthAuthorizations)) {
|
||||
newPath = newPath.replace(oauthAuthorizations, '/enterprise-server/v3/oauth_authorizations')
|
||||
}
|
||||
|
||||
// Change /v4/foo/bar to /v4/foo#bar
|
||||
// Change /v3/foo/bar to /v3/foo#bar
|
||||
// Then we can look up the hashless path in the redirect object,
|
||||
// get the new path like /graphql/reference/foo or /rest/reference/foo,
|
||||
// and add the #bar fragment back after.
|
||||
let fragment
|
||||
if (patterns.oldApiPath.test(newPath)) {
|
||||
// pathParts = [ '', 'v4', 'foo', 'bar' ]
|
||||
const pathParts = newPath.split('/')
|
||||
// lastSegment = bar
|
||||
const lastSegment = pathParts.pop()
|
||||
// newPath = /v4/foo
|
||||
newPath = pathParts.join('/')
|
||||
|
||||
// Underscores in the final segment of REST paths (`/admin_stats`)
|
||||
// get changed to hyphens when they become fragments (`#admin-stats`).
|
||||
// GraphQL paths rarely have underscores, but when they do, they are preserved (`__directive`).
|
||||
fragment = newPath.includes('/v3/')
|
||||
? lastSegment
|
||||
.replace(/_/g, '-')
|
||||
// this is a special oneoff replacement
|
||||
.replace('org-pre-receive-hooks', 'organization-pre-receive-hooks')
|
||||
.replace('repo-pre-receive-hooks', 'repository-pre-receive-hooks')
|
||||
: lastSegment
|
||||
}
|
||||
|
||||
// do a second lookup to find /v4/foo or /v3/foo without the last segment
|
||||
newPath = allRedirects[newPath] || newPath
|
||||
|
||||
// old developer routes that include 'enterprise-admin' should always redirect to enterprise server
|
||||
if (fragment && newPath.includes('/rest/reference/enterprise-admin') && !patterns.enterpriseServer.test(newPath)) {
|
||||
newPath = path.posix.join('/en', `enterprise-server@${latest}`, getPathWithoutLanguage(getPathWithoutVersion(newPath)))
|
||||
}
|
||||
|
||||
// show an error if the page to be redirected to doesn't exist
|
||||
// but only if the current collection of pages includes REST and GraphQL reference pages
|
||||
if (process.env.NODE_ENV !== 'test' && !pageMap[newPath] && pageMap['/en/rest/reference'] && pageMap['/en/graphql/reference']) {
|
||||
console.error(`can't find ${newPath}! based on ${oldDeveloperPath}`)
|
||||
}
|
||||
|
||||
// add fragment back in and return
|
||||
return fragment
|
||||
? newPath + '#' + fragment
|
||||
: newPath
|
||||
}
|
|
@ -29,14 +29,10 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren
|
|||
.replace(`/${languageCode}/enterprise/${latest}/user/insights`, '/insights'))
|
||||
|
||||
// create old path /desktop/guides from current path /desktop
|
||||
if (!currentPath.includes('/guides')) {
|
||||
oldPaths.add(currentPath
|
||||
.replace('/desktop', '/desktop/guides'))
|
||||
}
|
||||
|
||||
// create old path /admin/guides from current path /admin
|
||||
if (!currentPath.includes('/guides')) {
|
||||
oldPaths.add(currentPath
|
||||
.replace('/desktop', '/desktop/guides')
|
||||
.replace('/admin', '/admin/guides'))
|
||||
}
|
||||
|
||||
|
@ -90,10 +86,6 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren
|
|||
oldPaths.add(oldPath
|
||||
.replace(`/enterprise-server@${latest}`, '/enterprise-server'))
|
||||
|
||||
// create old path /enterprise-server@latest from new path /enterprise-server@<latest>
|
||||
oldPaths.add(oldPath
|
||||
.replace(`/enterprise-server@${latest}`, '/enterprise-server@latest'))
|
||||
|
||||
if (!patterns.adminProduct.test(oldPath)) {
|
||||
// create old path /enterprise/<version>/user/foo from new path /enterprise-server@<version>/foo
|
||||
oldPaths.add(currentPath
|
||||
|
@ -116,9 +108,6 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren
|
|||
|
||||
// add language code
|
||||
oldPaths.add(getPathWithLanguage(oldPath, languageCode))
|
||||
|
||||
// create /enterprise from /enterprise/latest
|
||||
oldPaths.add(oldPath.replace(`/enterprise/${latest}`, '/enterprise'))
|
||||
})
|
||||
|
||||
// exclude any empty old paths that may have been derived
|
||||
|
|
|
@ -1,40 +1,20 @@
|
|||
const { latest } = require('../enterprise-server-releases')
|
||||
const getDocsPathFromDevPath = require('../redirects/get-docs-path-from-developer-path')
|
||||
const DEVELOPER_ROUTES = require('../redirects/static/developer-docs-routes-for-supported-versions')
|
||||
const developerRedirects = require('../redirects/static/developer')
|
||||
const { latest } = require('../../lib/enterprise-server-releases')
|
||||
const latestDevRedirects = {}
|
||||
|
||||
// Replace hardcoded 'latest' with real value
|
||||
Object.entries(developerRedirects).forEach(([oldPath, newPath]) => {
|
||||
latestDevRedirects[oldPath] = newPath.replace('enterprise-server@latest', `enterprise-server@${latest}`)
|
||||
})
|
||||
|
||||
// This function runs at server warmup and precompiles possible redirect routes.
|
||||
// It outputs them in key-value pairs within a neat Javascript object: { oldPath: newPath }
|
||||
module.exports = function precompileRedirects (pageList, pageMap) {
|
||||
const allRedirects = {}
|
||||
module.exports = function precompileRedirects (pageList) {
|
||||
const allRedirects = Object.assign({}, latestDevRedirects)
|
||||
|
||||
// 1. CURRENT PAGES PERMALINKS AND FRONTMATTER
|
||||
// CURRENT PAGES PERMALINKS AND FRONTMATTER
|
||||
// create backwards-compatible old paths for page permalinks and frontmatter redirects
|
||||
pageList.forEach(page => Object.assign(allRedirects, page.buildRedirects()))
|
||||
|
||||
// 2. DEVELOPER ROUTES FOR CURRENTLY SUPPORTED VERSIONS
|
||||
// From the list of developer docs routes, create new docs.github.com-style paths.
|
||||
// Note that the list only includes supported enterprise paths up to 2.21, which is
|
||||
// the last version that was available on developer.github.com before the migration.
|
||||
DEVELOPER_ROUTES.forEach(developerRoute => {
|
||||
const newPath = getDocsPathFromDevPath(developerRoute, allRedirects, pageMap)
|
||||
|
||||
// add the redirect to the object
|
||||
allRedirects[developerRoute] = newPath
|
||||
|
||||
// also add a variation with language code
|
||||
const developerRouteWithLanguage = `/en${developerRoute}`
|
||||
allRedirects[developerRouteWithLanguage] = newPath
|
||||
|
||||
// although we only support developer Enterprise paths up to 2.21, we make
|
||||
// an exception to always redirect versionless paths to the latest version
|
||||
if (developerRoute.includes('/2.21/')) {
|
||||
const newPathOnLatestVersion = newPath.replace('@2.21/', `@${latest}/`)
|
||||
const developerRouteWithoutVersion = developerRoute.replace('/2.21/', '/')
|
||||
const developerRouteWithLanguageWithoutVersion = `/en${developerRouteWithoutVersion}`
|
||||
allRedirects[developerRouteWithoutVersion] = newPathOnLatestVersion
|
||||
allRedirects[developerRouteWithLanguageWithoutVersion] = newPathOnLatestVersion
|
||||
}
|
||||
})
|
||||
|
||||
return allRedirects
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,12 +1,12 @@
|
|||
const path = require('path')
|
||||
const slash = require('slash')
|
||||
const { latest, firstVersionDeprecatedOnNewSite, lastVersionWithoutStubbedRedirectFiles } = require('../lib/enterprise-server-releases')
|
||||
const { firstVersionDeprecatedOnNewSite, lastVersionWithoutStubbedRedirectFiles } = require('../lib/enterprise-server-releases')
|
||||
const patterns = require('../lib/patterns')
|
||||
const versionSatisfiesRange = require('../lib/version-satisfies-range')
|
||||
const isArchivedVersion = require('../lib/is-archived-version')
|
||||
const findPage = require('../lib/find-page')
|
||||
const got = require('got')
|
||||
const archvivedRedirects = require('../lib/redirects/static/archived-redirects-from-213-to-217')
|
||||
const archivedFrontmatterFallbacks = require('../lib/redirects/static/archived-frontmatter-fallbacks')
|
||||
|
||||
// This module handles requests for deprecated GitHub Enterprise versions
|
||||
// by routing them to static content in help-docs-archived-enterprise-versions
|
||||
|
@ -75,23 +75,5 @@ function getFallbackRedirects (req, requestedVersion) {
|
|||
if (versionSatisfiesRange(requestedVersion, `<${firstVersionDeprecatedOnNewSite}`)) return
|
||||
if (versionSatisfiesRange(requestedVersion, `>${lastVersionWithoutStubbedRedirectFiles}`)) return
|
||||
|
||||
const pathWithNewVersion = req.path.replace(requestedVersion, latest)
|
||||
|
||||
// look for a page with the same path on a currently supported version
|
||||
const currentlySupportedPage = findPage(pathWithNewVersion, req.context.pages, req.context.redirects)
|
||||
if (!currentlySupportedPage) return
|
||||
|
||||
// get an array of viable old paths
|
||||
return Object.keys(currentlySupportedPage.redirects)
|
||||
// filter for just languageless and versionless enterprise old paths
|
||||
// example: [
|
||||
// '/enterprise/user/articles/viewing-contributions',
|
||||
// '/enterprise/user/articles/viewing-contributions-on-your-profile-page',
|
||||
// '/enterprise/user/articles/viewing-contributions-on-your-profile'
|
||||
// ]
|
||||
.filter(oldPath => oldPath.startsWith('/enterprise') && patterns.enterpriseNoVersion.test(oldPath))
|
||||
// add in the current language and version
|
||||
.map(oldPath => slash(path.join('/', req.context.currentLanguage, oldPath.replace('/enterprise/', `/enterprise/${requestedVersion}/`))))
|
||||
// ignore paths that match the requested path
|
||||
.filter(oldPath => oldPath !== req.path)
|
||||
return archivedFrontmatterFallbacks.find(arrayOfFallbacks => arrayOfFallbacks.includes(req.path))
|
||||
}
|
||||
|
|
|
@ -4886,6 +4886,14 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/mdast": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz",
|
||||
"integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==",
|
||||
"requires": {
|
||||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||
|
@ -5267,7 +5275,7 @@
|
|||
},
|
||||
"agentkeepalive": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz",
|
||||
"integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8="
|
||||
},
|
||||
"aggregate-error": {
|
||||
|
@ -5405,7 +5413,7 @@
|
|||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
|
@ -6788,7 +6796,7 @@
|
|||
},
|
||||
"brfs": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz",
|
||||
"integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==",
|
||||
"requires": {
|
||||
"quote-stream": "^1.0.1",
|
||||
|
@ -9492,7 +9500,7 @@
|
|||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=",
|
||||
"requires": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
|
@ -17924,7 +17932,7 @@
|
|||
},
|
||||
"magic-string": {
|
||||
"version": "0.22.5",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
|
||||
"resolved": "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
|
||||
"integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==",
|
||||
"requires": {
|
||||
"vlq": "^0.2.2"
|
||||
|
@ -18028,6 +18036,51 @@
|
|||
"integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==",
|
||||
"requires": {
|
||||
"unist-util-visit": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mdast-util-from-markdown": {
|
||||
"version": "0.8.4",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.4.tgz",
|
||||
"integrity": "sha512-jj891B5pV2r63n2kBTFh8cRI2uR9LQHsXG1zSDqfhXkIlDzrTcIlbB5+5aaYEkl8vOPIOPLf8VT7Ere1wWTMdw==",
|
||||
"requires": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"mdast-util-to-string": "^2.0.0",
|
||||
"micromark": "~2.11.0",
|
||||
"parse-entities": "^2.0.0",
|
||||
"unist-util-stringify-position": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"parse-entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
|
||||
"integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
|
||||
"requires": {
|
||||
"character-entities": "^1.0.0",
|
||||
"character-entities-legacy": "^1.0.0",
|
||||
"character-reference-invalid": "^1.0.0",
|
||||
"is-alphanumerical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0",
|
||||
"is-hexadecimal": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mdast-util-to-hast": {
|
||||
|
@ -18046,8 +18099,31 @@
|
|||
"unist-util-position": "^3.0.0",
|
||||
"unist-util-visit": "^1.1.0",
|
||||
"xtend": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mdast-util-to-string": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
|
||||
"integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w=="
|
||||
},
|
||||
"mdurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
|
@ -18190,6 +18266,43 @@
|
|||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"micromark": {
|
||||
"version": "2.11.2",
|
||||
"resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.2.tgz",
|
||||
"integrity": "sha512-IXuP76p2uj8uMg4FQc1cRE7lPCLsfAXuEfdjtdO55VRiFO1asrCSQ5g43NmPqFtRwzEnEhafRVzn2jg0UiKArQ==",
|
||||
"requires": {
|
||||
"debug": "^4.0.0",
|
||||
"parse-entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"parse-entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
|
||||
"integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
|
||||
"requires": {
|
||||
"character-entities": "^1.0.0",
|
||||
"character-entities-legacy": "^1.0.0",
|
||||
"character-reference-invalid": "^1.0.0",
|
||||
"is-alphanumerical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0",
|
||||
"is-hexadecimal": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||
|
@ -20575,6 +20688,24 @@
|
|||
"hast-util-has-property": "^1.0.0",
|
||||
"hast-util-is-element": "^1.0.0",
|
||||
"unist-util-visit": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rehype-highlight": {
|
||||
|
@ -20585,6 +20716,24 @@
|
|||
"hast-util-to-text": "^1.0.0",
|
||||
"lowlight": "^1.10.0",
|
||||
"unist-util-visit": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rehype-raw": {
|
||||
|
@ -20605,6 +20754,24 @@
|
|||
"hast-util-is-element": "^1.0.0",
|
||||
"hast-util-to-string": "^1.0.0",
|
||||
"unist-util-visit": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rehype-stringify": {
|
||||
|
@ -20627,6 +20794,24 @@
|
|||
"integrity": "sha512-MHKTd2zsKc9ayrLBaUzyiIw7rNY4Q/aNSx1L1xss7ZthQ/oSEoMvtA5wpXALVKTWOL5JQXDf/Q9lP8IWbP3cig==",
|
||||
"requires": {
|
||||
"unist-util-visit": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remark-gemoji-to-emoji": {
|
||||
|
@ -20636,6 +20821,24 @@
|
|||
"requires": {
|
||||
"gemoji": "^4.0.0",
|
||||
"unist-util-visit": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remark-parse": {
|
||||
|
@ -23197,6 +23400,24 @@
|
|||
"integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==",
|
||||
"requires": {
|
||||
"unist-util-visit": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"unist-util-stringify-position": {
|
||||
|
@ -23208,19 +23429,36 @@
|
|||
}
|
||||
},
|
||||
"unist-util-visit": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
|
||||
"integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
|
||||
"integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
|
||||
"requires": {
|
||||
"unist-util-visit-parents": "^2.0.0"
|
||||
"@types/unist": "^2.0.0",
|
||||
"unist-util-is": "^4.0.0",
|
||||
"unist-util-visit-parents": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-is": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz",
|
||||
"integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"unist-util-visit-parents": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
|
||||
"integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
|
||||
"integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
|
||||
"requires": {
|
||||
"unist-util-is": "^3.0.0"
|
||||
"@types/unist": "^2.0.0",
|
||||
"unist-util-is": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"unist-util-is": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz",
|
||||
"integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"universal-user-agent": {
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"linkinator": "^2.13.1",
|
||||
"liquid": "^5.1.0",
|
||||
"lodash": "^4.17.19",
|
||||
"mdast-util-from-markdown": "^0.8.4",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"mkdirp": "^1.0.3",
|
||||
"morgan": "^1.9.1",
|
||||
|
@ -86,6 +87,7 @@
|
|||
"slash": "^3.0.0",
|
||||
"strip-html-comments": "^1.0.0",
|
||||
"style-loader": "^1.2.1",
|
||||
"unist-util-visit": "^2.0.3",
|
||||
"uuid": "^8.3.0",
|
||||
"walk-sync": "^1.1.4",
|
||||
"webpack": "^4.44.0",
|
||||
|
|
|
@ -48,7 +48,9 @@ const main = async () => {
|
|||
'uuid',
|
||||
'imurmurhash',
|
||||
'js-cookie',
|
||||
'clipboard'
|
||||
'clipboard',
|
||||
'mdast-util-from-markdown',
|
||||
'unist-util-visit'
|
||||
]
|
||||
})
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@ const fs = require('fs')
|
|||
const walk = require('walk-sync')
|
||||
const { zip } = require('lodash')
|
||||
const yaml = require('js-yaml')
|
||||
const revalidator = require('revalidator')
|
||||
const generateMarkdownAST = require('mdast-util-from-markdown')
|
||||
const visit = require('unist-util-visit')
|
||||
const frontmatter = require('../../lib/frontmatter')
|
||||
const languages = require('../../lib/languages')
|
||||
const { tags } = require('../../lib/liquid-tags/extended-markdown')
|
||||
const ghesReleaseNotesSchema = require('../../lib/release-notes-schema')
|
||||
const revalidator = require('revalidator')
|
||||
|
||||
const rootDir = path.join(__dirname, '../..')
|
||||
const contentDir = path.join(rootDir, 'content')
|
||||
|
@ -164,16 +166,22 @@ describe('lint-files', () => {
|
|||
describe.each([...contentMarkdownTuples, ...reusableMarkdownTuples])(
|
||||
'in "%s"',
|
||||
(markdownRelPath, markdownAbsPath) => {
|
||||
let content, isHidden, isEarlyAccess, isSitePolicy
|
||||
let content, ast, links, isHidden, isEarlyAccess, isSitePolicy
|
||||
|
||||
beforeAll(async () => {
|
||||
const fileContents = await fs.promises.readFile(markdownAbsPath, 'utf8')
|
||||
const { data, content: bodyContent } = frontmatter(fileContents)
|
||||
|
||||
content = bodyContent
|
||||
ast = generateMarkdownAST(content)
|
||||
isHidden = data.hidden === true
|
||||
isEarlyAccess = markdownRelPath.split('/').includes('early-access')
|
||||
isSitePolicy = markdownRelPath.split('/').includes('site-policy-deprecated')
|
||||
|
||||
links = []
|
||||
visit(ast, ['link', 'definition'], node => {
|
||||
links.push(node.url)
|
||||
})
|
||||
})
|
||||
|
||||
// We need to support some non-Early Access hidden docs in Site Policy
|
||||
|
@ -184,58 +192,16 @@ describe('lint-files', () => {
|
|||
})
|
||||
|
||||
test('relative URLs must start with "/"', async () => {
|
||||
const initialMatches = (content.match(relativeArticleLinkRegex) || [])
|
||||
const matches = links.filter(link => {
|
||||
if (
|
||||
link.startsWith('http://') ||
|
||||
link.startsWith('https://') ||
|
||||
link.startsWith('tel:') ||
|
||||
link.startsWith('mailto:') ||
|
||||
link.startsWith('#') ||
|
||||
link.startsWith('/')
|
||||
) return false
|
||||
|
||||
// Filter out some very specific false positive matches
|
||||
const matches = initialMatches.filter(match => {
|
||||
if (markdownRelPath === 'content/github/enforcing-best-practices-with-github-policies/overview.md') {
|
||||
if (match === '[A-Z]([a-z]|-)') {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/github/enforcing-best-practices-with-github-policies/constraints.md') {
|
||||
if (match === '[a-z]([a-z]|-)') {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/github/building-a-strong-community/editing-wiki-content.md') {
|
||||
if (match === '[Link Text](full-URL-of-wiki-page)') {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/admin/configuration/configuring-email-for-notifications.md') {
|
||||
if (/^\[\d+\]: (?:connect|disconnect|[0-9A-F]+:)\s*$/.test(match)) {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners.md') {
|
||||
if (/^\[\d+\]: (?:Starting|Started|√|\d{4}-\d{2}-\d{2})\s*$/.test(match)) {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/github/finding-security-vulnerabilities-and-errors-in-your-code/sarif-support-for-code-scanning.md') {
|
||||
if (/^\[(?:here|ruleIndex|ruleID)\]\(\d+\)\s*$/.test(match)) {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/github/building-a-strong-community/manually-creating-a-single-issue-template-for-your-repository.md') {
|
||||
if (match === '[DATE]: [FEATURE ') {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/rest/overview/libraries.md') {
|
||||
if (
|
||||
match === '[pithub-github] ([CPAN][pithub-cpan])' ||
|
||||
match === '[net-github-github] ([CPAN][net-github-cpan])'
|
||||
) {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'data/reusables/repositories/relative-links.md') {
|
||||
if (match === '[Contribution guidelines for this project](docs/CONTRIBUTING.md)') {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/early-access/github/enforcing-best-practices-with-github-policies/constraints.md') {
|
||||
if (match === '[a-z]([a-z]|-)') {
|
||||
return false
|
||||
}
|
||||
} else if (markdownRelPath === 'content/early-access/github/enforcing-best-practices-with-github-policies/overview.md') {
|
||||
if (match === '[A-Z]([a-z]|-)') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
|
@ -244,7 +210,10 @@ describe('lint-files', () => {
|
|||
})
|
||||
|
||||
test('URLs must not contain a hard-coded language code', async () => {
|
||||
const matches = (content.match(languageLinkRegex) || [])
|
||||
const matches = links.filter(link => {
|
||||
return /\/(?:${languageCodes.join('|')})\//.test(link)
|
||||
})
|
||||
|
||||
const errorMessage = formatLinkError(languageLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
|
|
@ -329,8 +329,8 @@ describe('server', () => {
|
|||
})
|
||||
|
||||
test('admin articles that link to Enterprise user articles have Enterprise user links', async () => {
|
||||
const $ = await getDOM(`${latestEnterprisePath}/admin/user-management/configuring-email-for-notifications`)
|
||||
expect($('article a[href*="about-email-notifications-for-pushes-to-your-repository"]').length).toBe(1)
|
||||
const $ = await getDOM(`${latestEnterprisePath}/admin/user-management/customizing-user-messages-for-your-enterprise`)
|
||||
expect($('article a[href*="about-writing-and-formatting-on-github"]').length).toBe(1)
|
||||
})
|
||||
|
||||
test('articles that link to external links that contain /articles/ are not rewritten', async () => {
|
||||
|
|
|
@ -120,7 +120,7 @@ describe('developer redirects', () => {
|
|||
newPath = newPath.replace('/enterprise-server/', `/enterprise-server@${enterpriseServerReleases.latest}/`)
|
||||
const res = await get(oldPath)
|
||||
expect(res.statusCode, `${oldPath} did not redirect to ${newPath}`).toBe(301)
|
||||
expect(res.headers.location).toBe(newPath)
|
||||
expect(res.headers.location, `${oldPath} did not redirect to ${newPath}`).toBe(newPath)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -136,7 +136,7 @@ describe('developer redirects', () => {
|
|||
newPath = newPath.replace('/enterprise-server/', `/enterprise-server@${enterpriseServerReleases.latest}/`)
|
||||
const res = await get(oldPath)
|
||||
expect(res.statusCode, `${oldPath} did not redirect to ${newPath}`).toBe(301)
|
||||
expect(res.headers.location).toBe(newPath)
|
||||
expect(res.headers.location, `${oldPath} did not redirect to ${newPath}`).toBe(newPath)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
Загрузка…
Ссылка в новой задаче