Browse Source

GitHub Actions: Check URLs using lychee (#1169)

This makes it possible to be aware of dead links and replace
them with other resources (such as archived versions) as
soon as possible.
Hugo Locurcio 2 months ago
parent
commit
a0f59648f2

+ 36 - 0
.github/workflows/check_urls.yml

@@ -0,0 +1,36 @@
+name: 🌐 Check URLs
+on:
+  push:
+  pull_request:
+  schedule:
+    # Every day at 18:00 UTC.
+    # URLs can decay over time. Setting up a schedule makes it possible to be warned
+    # about dead links as soon as possible.
+    - cron: "0 18 * * *"
+
+jobs:
+  check-urls:
+    runs-on: ubuntu-24.04
+    steps:
+
+      - uses: actions/checkout@v4
+
+      - name: Restore lychee cache
+        uses: actions/cache@v4
+        with:
+          path: .lycheecache
+          key: cache-lychee-${{ github.sha }}
+          restore-keys: cache-lychee-
+
+      - name: Run lychee
+        uses: lycheeverse/lychee-action@v2
+        with:
+          args: >
+            --base .
+            --no-progress
+            --cache
+            --max-cache-age 1d
+            "**/*.md" "**/*.gd" "**/*.cs" "**/*.tscn" "**/*.tres" "**/*.html"
+
+      - name: Fail if there were link errors
+        run: exit ${{ steps.lc.outputs.exit_code }}

+ 30 - 0
.lycheeignore

@@ -0,0 +1,30 @@
+# Don't read Godot's own URL schemes as web URLs.
+user:\/\/.*
+res:\/\/.*
+uid:\/\/.*
+
+# Don't read WebSockets or TCP URLs as web URLs.
+ws(s?):\/\/.*
+tcp:\/\/.*
+
+# Security checks prevent checking the URLs of these websites automatically,
+# typically returning 403 errors.
+.*asecuritysite\.com.*
+.*intel\.com.*
+.*reddit\.com.*
+
+# Don't check URLs from these websites due to frequent rate limits (error 429) or timeouts.
+.*adobe\.com.*
+.*gamedevartisan\.com.*
+.*github\.com.*
+.*gnu\.org.*
+.*loopit\.dk.*
+.*meta\.com.*
+.*sourceforge\.io.*
+
+# Not a valid URL with the GET method, which lychee always sends.
+# Mentioned in the class reference.
+.*httpbin\.org\/post
+
+# Class reference mentions `example.com/index.php` in an example, which is 404.
+.*example\.com.*

+ 1 - 1
3d/ik/README.md

@@ -11,7 +11,7 @@ Renderer: Forward+
 ## How does it work?
 ## How does it work?
 
 
 This demo shows how to implement IK using two different methods. One uses the
 This demo shows how to implement IK using two different methods. One uses the
-[`SkeletonIK`](https://docs.godotengine.org/en/latest/classes/class_skeletonik.html)
+[`SkeletonIK3D`](https://docs.godotengine.org/en/latest/classes/class_skeletonik3d.html)
 node which is built into Godot. The other method is using a script
 node which is built into Godot. The other method is using a script
 called FABRIK (inside of the SADE plugin) for inverse kinematics.
 called FABRIK (inside of the SADE plugin) for inverse kinematics.
 
 

+ 2 - 2
3d/truck_town/README.md

@@ -29,11 +29,11 @@ Check out this demo on the asset library: https://godotengine.org/asset-library/
 The base vehicle uses a
 The base vehicle uses a
 [`VehicleBody3D`](https://docs.godotengine.org/en/latest/classes/class_vehiclebody3d.html)
 [`VehicleBody3D`](https://docs.godotengine.org/en/latest/classes/class_vehiclebody3d.html)
 node. The trailer truck is tied together using a
 node. The trailer truck is tied together using a
-[`ConeJointTwist`](https://docs.godotengine.org/en/latest/classes/class_conetwistjoint.html)
+[`ConeJointTwist3D`](https://docs.godotengine.org/en/latest/classes/class_conetwistjoint3d.html)
 node, and the tow truck is tried together using a chain made of
 node, and the tow truck is tried together using a chain made of
 [`RigidBody3D`](https://docs.godotengine.org/en/latest/classes/class_rigidbody3d.html)
 [`RigidBody3D`](https://docs.godotengine.org/en/latest/classes/class_rigidbody3d.html)
 nodes which are pinned together using
 nodes which are pinned together using
-[`PinJoint`](https://docs.godotengine.org/en/latest/classes/class_pinjoint.html) nodes.
+[`PinJoint3D`](https://docs.godotengine.org/en/latest/classes/class_pinjoint3d.html) nodes.
 
 
 ## Screenshots
 ## Screenshots
 
 

+ 3 - 3
3d/voxel/README.md

@@ -14,7 +14,7 @@ Check out this demo on the asset library: https://godotengine.org/asset-library/
 Each chunk is a
 Each chunk is a
 [`StaticBody3D`](https://docs.godotengine.org/en/latest/classes/class_staticbody3d.html)
 [`StaticBody3D`](https://docs.godotengine.org/en/latest/classes/class_staticbody3d.html)
 with each block having its own
 with each block having its own
-[`CollisionShape`](https://docs.godotengine.org/en/latest/classes/class_collisionshape.html)
+[`CollisionShape3D`](https://docs.godotengine.org/en/latest/classes/class_collisionshape3d.html)
 for collisions. The meshes are created using
 for collisions. The meshes are created using
 [`SurfaceTool`](https://docs.godotengine.org/en/latest/classes/class_surfacetool.html)
 [`SurfaceTool`](https://docs.godotengine.org/en/latest/classes/class_surfacetool.html)
 which allows specifying vertices, triangles, and UV coordinates
 which allows specifying vertices, triangles, and UV coordinates
@@ -30,7 +30,7 @@ are two terrain types, random blocks and flat grass. A more
 complex terrain generator is out-of-scope for this demo project.
 complex terrain generator is out-of-scope for this demo project.
 
 
 The player can place and break blocks using the
 The player can place and break blocks using the
-[`RayCast`](https://docs.godotengine.org/en/latest/classes/class_raycast.html)
+[`RayCast3D`](https://docs.godotengine.org/en/latest/classes/class_raycast3d.html)
 node attached to the camera. It uses the collision information to
 node attached to the camera. It uses the collision information to
 figure out the block position and change the block data. You can
 figure out the block position and change the block data. You can
 switch the active block using the brackets or with the middle mouse button.
 switch the active block using the brackets or with the middle mouse button.
@@ -40,7 +40,7 @@ Settings are stored inside of an
 [AutoLoad singleton](https://docs.godotengine.org/en/latest/getting_started/step_by_step/singletons_autoload.html)
 [AutoLoad singleton](https://docs.godotengine.org/en/latest/getting_started/step_by_step/singletons_autoload.html)
 called "Settings". This class will automatically save
 called "Settings". This class will automatically save
 settings, and load them when the game opens, by using the
 settings, and load them when the game opens, by using the
-[`File`](https://docs.godotengine.org/en/latest/classes/class_file.html) class.
+[`FileAccess`](https://docs.godotengine.org/en/latest/classes/class_fileaccess.html) class.
 
 
 Sticking to GDScript and the built-in Godot tools, as this demo does, is
 Sticking to GDScript and the built-in Godot tools, as this demo does, is
 quite limiting. If you are making your own voxel game, you should probably
 quite limiting. If you are making your own voxel game, you should probably

+ 1 - 1
audio/audio_effects/README.md

@@ -36,4 +36,4 @@ All sound effects are from [Freesound](https://freesound.org/) and licensed unde
 - [Static](https://freesound.org/people/dotY21/sounds/335203/) by dotY21
 - [Static](https://freesound.org/people/dotY21/sounds/335203/) by dotY21
 
 
 ### Icon
 ### Icon
-- [Equalizer](https://iconduck.com/icons/249702/equalizer) and licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
+- Equalizer licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

+ 2 - 2
loading/runtime_save_load/README.md

@@ -31,7 +31,7 @@ this demo.
 [^3]: There are known issues with runtime FBX loading, as mentioned in issue
 [^3]: There are known issues with runtime FBX loading, as mentioned in issue
 [#96043](https://github.com/godotengine/godot/issues/96043).
 [#96043](https://github.com/godotengine/godot/issues/96043).
 
 
-See the [Saving and Loading (Serialization)](/loading/serialization/) demo for
+See the [Saving and Loading (Serialization)](../serialization/) demo for
 an example of saving/loading game progress.
 an example of saving/loading game progress.
 
 
 Language: GDScript
 Language: GDScript
@@ -49,5 +49,5 @@ Check out this demo on the asset library: https://godotengine.org/asset-library/
 - Files in `examples/3d_scenes/gltf/` are copyright
 - Files in `examples/3d_scenes/gltf/` are copyright
   [Poly Haven](https://polyhaven.com/a/plastic_monobloc_chair_01)
   [Poly Haven](https://polyhaven.com/a/plastic_monobloc_chair_01)
   and are licensed under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/).
   and are licensed under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/).
-- Files in `examples/audio/` are copyright [Red Eclipse](https://redeclipse.net)
+- Files in `examples/audio/` are copyright [Red Eclipse](https://www.redeclipse.net/)
   and are licensed under [CC BY-SA 4.0 International](https://www.creativecommons.org/licenses/by-sa/4.0/).
   and are licensed under [CC BY-SA 4.0 International](https://www.creativecommons.org/licenses/by-sa/4.0/).

+ 1 - 1
loading/serialization/README.md

@@ -11,7 +11,7 @@ More formats may be added in the future.
 For more information, see [Saving games](https://docs.godotengine.org/en/latest/tutorials/io/saving_games.html)
 For more information, see [Saving games](https://docs.godotengine.org/en/latest/tutorials/io/saving_games.html)
 in the documentation.
 in the documentation.
 
 
-See the [Run-time File Saving and Loading](/loading/runtime_save_load/) demo for
+See the [Run-time File Saving and Loading](../runtime_save_load/) demo for
 an example of loading various file types in an exported project without needing
 an example of loading various file types in an exported project without needing
 to import them.
 to import them.