Fix distribution tarballs and update changelog and version for release 1.4.0 (#429)

* Fix location of MODULE.bazel in distro tarballs.
* Remove invalid paths from WORKSPACE files in distro tarballs
* The resulting tarballs should finally be distributable as 1.4.0 in BCR.
diff --git a/BUILD b/BUILD
index 8425403..11751a9 100644
--- a/BUILD
+++ b/BUILD
@@ -10,6 +10,7 @@
 exports_files([
     "LICENSE",
     "MODULE.bazel",
+    "WORKSPACE",
 ])
 
 filegroup(
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ef9c469..2e3ff6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+Release 1.4.0
+
+**New Features**
+-   The Gazelle plugin is marked stable for general use (#400, #424)
+
+**Other Notable Changes**
+-   copy_file/copy_directory again allow sandboxing (#392)
+
+**Contributors**
+Alexandre Rostovtsev, Nick Gooding, Simon Stewart, Xùdōng Yáng
+
+
 Release 1.3.0
 
 **New Features**
diff --git a/MODULE.bazel b/MODULE.bazel
index a8de50f..1d18e9a 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -1,7 +1,7 @@
 module(
     name = "bazel_skylib",
     # Keep in sync with version.bzl and @bazel_skylib_gazelle_plugin//:MODULE.bazel
-    version = "1.3.0",
+    version = "1.4.0",
     compatibility_level = 1,
 )
 
diff --git a/README.md b/README.md
index 1954aa3..4c6764e 100644
--- a/README.md
+++ b/README.md
@@ -144,7 +144,7 @@
 
 bazel_skylib_gazelle_plugin_workspace()
 
-load("@bazel_skylib_gazelle_plugin//:setup.bzl", "bazel_skylib_gazelle_plugin_setup"
+load("@bazel_skylib_gazelle_plugin//:setup.bzl", "bazel_skylib_gazelle_plugin_setup")
 
 bazel_skylib_gazelle_plugin_setup()
 ```
@@ -163,7 +163,7 @@
 gazelle_binary(
     name = "gazelle_bin",
     languages = DEFAULT_LANGUAGES + [
-        "@bazel_skylib_gazelle_plugin//gazelle/bzl",
+        "@bazel_skylib_gazelle_plugin//bzl",
     ],
 )
 ```
diff --git a/WORKSPACE b/WORKSPACE
index 0cfb154..1b551a3 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,11 +1,16 @@
 workspace(name = "bazel_skylib")
 
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
 load(":workspace.bzl", "bazel_skylib_workspace")
 
 bazel_skylib_workspace()
 
+### INTERNAL ONLY - lines after this are not included in the release packaging.
+# Lines below are for tests, documentation generation, and distribution archive
+# generation only, and should thus not be included by dependencies on bazel-skylib.
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
+
 local_repository(
     name = "bazel_skylib_gazelle_plugin",
     path = "gazelle",
@@ -19,10 +24,6 @@
 
 bazel_skylib_gazelle_plugin_setup()
 
-# Below this line is for documentation generation only,
-# and should thus not be included by dependencies on
-# bazel-skylib.
-
 maybe(
     http_archive,
     name = "io_bazel_stardoc",
diff --git a/distribution/BUILD b/distribution/BUILD
index 8762525..1aa737c 100644
--- a/distribution/BUILD
+++ b/distribution/BUILD
@@ -1,3 +1,4 @@
+load("distribution.bzl", "remove_internal_only")
 load("@bazel_skylib//:version.bzl", "version")
 load("@rules_pkg//:pkg.bzl", "pkg_tar")
 load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
@@ -6,18 +7,32 @@
     default_visibility = ["//visibility:private"],
 )
 
-genrule(
-    name = "distro_module_bazel",
-    srcs = ["//:MODULE.bazel"],
-    outs = ["MODULE.bazel"],
-    cmd = "sed -e '/### INTERNAL ONLY/,$$d' $(location //:MODULE.bazel) >$@",
+remove_internal_only(
+    name = "distro_workspace",
+    src = "//:WORKSPACE",
+    out = "WORKSPACE",
 )
 
-# Build the artifacts to put on the github release page.
+remove_internal_only(
+    name = "distro_module_bazel",
+    src = "//:MODULE.bazel",
+    out = "MODULE.bazel",
+)
+
+# remove "distribution/" path prefix
+pkg_files(
+    name = "distro-files-without-prefix",
+    srcs = [
+        "distro_module_bazel",
+        "distro_workspace",
+    ],
+    strip_prefix = strip_prefix.from_pkg(),
+)
+
 pkg_tar(
     name = "bazel-skylib",
     srcs = [
-        "distro_module_bazel",
+        "distro-files-without-prefix",
         "//:distribution",
     ],
     out = "bazel-skylib-%s.tar.gz" % version,
@@ -28,6 +43,14 @@
     strip_prefix = strip_prefix.from_root(),
 )
 
+# @bazel_skylib_gazelle_plugin//:WORKSPACE refers to bazel-skylib in the parent
+# directory. For distribution, use the minimal WORSKPACE.bzlmod instead.
+pkg_files(
+    name = "bazel-skylib-gazelle-plugin-distro_workspace",
+    srcs = ["@bazel_skylib_gazelle_plugin//:WORKSPACE.bzlmod"],
+    renames = {"@bazel_skylib_gazelle_plugin//:WORKSPACE.bzlmod": "WORKSPACE"},
+)
+
 pkg_files(
     name = "bazel-skylib-gazelle-plugin-without-external-prefix",
     srcs = [
@@ -40,7 +63,8 @@
 pkg_tar(
     name = "bazel-skylib-gazelle-plugin",
     srcs = [
-        ":bazel-skylib-gazelle-plugin-without-external-prefix",
+        "bazel-skylib-gazelle-plugin-distro_workspace",
+        "bazel-skylib-gazelle-plugin-without-external-prefix",
         "//:LICENSE",
     ],
     out = "bazel-skylib-gazelle-plugin-%s.tar.gz" % version,
@@ -50,6 +74,7 @@
     owner = "0.0",
 )
 
+# Build the artifacts to put on the github release page.
 filegroup(
     name = "distribution",
     srcs = [
diff --git a/distribution/distribution.bzl b/distribution/distribution.bzl
new file mode 100644
index 0000000..e1dd14e
--- /dev/null
+++ b/distribution/distribution.bzl
@@ -0,0 +1,32 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Helper utilities for generating distribution tarballs."""
+
+def remove_internal_only(name, src, out, **kwargs):
+    """Removes '### INTERNAL ONLY' line and all lines below from a file.
+
+    Args:
+        name: Name of the rule.
+        src: File to process.
+        out: Path of the output file.
+        **kwargs: further keyword arguments.
+    """
+    native.genrule(
+        name = name,
+        srcs = [src],
+        outs = [out],
+        cmd = "sed -e '/### INTERNAL ONLY/,$$d' $< >$@",
+        **kwargs
+    )
diff --git a/gazelle/BUILD b/gazelle/BUILD
index ff51bab..d1c6daa 100644
--- a/gazelle/BUILD
+++ b/gazelle/BUILD
@@ -1,5 +1,7 @@
 load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
 
+exports_files(["WORKSPACE.bzlmod"])
+
 bzl_library(
     name = "setup",
     srcs = ["setup.bzl"],
@@ -24,9 +26,12 @@
 # TODO(arostovtsev): exclude everything below from distro tarball
 filegroup(
     name = "distribution",
-    srcs = glob(
-        ["*"],
-        allow_empty = True,
-    ),
+    srcs = [
+        "BUILD",
+        "MODULE.bazel",
+        "WORKSPACE.bzlmod",
+        "setup.bzl",
+        "workspace.bzl",
+    ],
     visibility = ["//visibility:public"],
 )
diff --git a/gazelle/MODULE.bazel b/gazelle/MODULE.bazel
index b897c81..8e51543 100644
--- a/gazelle/MODULE.bazel
+++ b/gazelle/MODULE.bazel
@@ -1,12 +1,12 @@
 module(
     name = "bazel_skylib_gazelle_plugin",
     # Keep in sync with @bazel_skylib//:MODULE.bazel and @bazel_skylib//:version.bzl
-    version = "1.3.0",
+    version = "1.4.0",
     compatibility_level = 1,
 )
 
 # Keep in sync with @bazel_skylib//:MODULE.bazel and @bazel_skylib//:version.bzl
-bazel_dep(name = "bazel_skylib", version = "1.3.0")
+bazel_dep(name = "bazel_skylib", version = "1.4.0")
 bazel_dep(name = "gazelle", version = "0.28.0", repo_name = "bazel_gazelle")
 bazel_dep(name = "rules_go", version = "0.35.0", repo_name = "io_bazel_rules_go")
 
diff --git a/version.bzl b/version.bzl
index 0bcd28a..4d352a3 100644
--- a/version.bzl
+++ b/version.bzl
@@ -14,4 +14,4 @@
 """The version of bazel-skylib."""
 
 # Keep in sync with MODULE.bazel and @bazel_skylib_gazelle_plugin//:MODULE.bazel
-version = "1.3.0"
+version = "1.4.0"