-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CICD-761] Generate a dynamic excludes file list for rsync #40
Conversation
Outputs the list to stdout, which is called with process substitution in the initial rsync command. Also disables debug mode for the block calling the generate function. This prevents unwanted debug output (specific to the excludes list generation) from being shown.
Moves the test-plugin (used by e2e test) to a wp-content dir for reuse as a fixture in unit testing.
Resolves a warning about unused variables in the common file.
🦋 Changeset detectedLatest commit: cec397d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
.github/workflows/e2e-deploy.yml
Outdated
@@ -19,15 +19,15 @@ jobs: | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- name: Bump test plugin version number | |||
run: sed -i 's/0.0.1/0.0.2/' tests/data/plugins/test-plugin/test-plugin.php | |||
run: sed -i 's/0.0.1/0.0.2/' tests/data/wp-content/plugins/test-plugin/test-plugin.php |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plugin used for e2e tests was moved to reside under a wp-content
parent dir. The reasoning was to make the file structure more closely resemble a WordPress install, making the plugin reusable for unit testing.
entrypoint.sh
Outdated
# Generate the excludes list before using the output with rsync | ||
local exclude_from; exclude_from="$(generate_exclude_from)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found it preferable to generate the output in a variable here.
The text works more reliably when quoted, and while calling the function directly in the process substitution works (eg, <(echo "generate_exclude_from")
), it produces warnings about a needless echo.
entrypoint.sh
Outdated
#create multiplex connection | ||
ssh -nNf -v -i "${WPE_SSHG_KEY_PRIVATE_PATH}" -o StrictHostKeyChecking=no -o ControlMaster=yes -o ControlPath="$SSH_PATH/ctl/%C" "$WPE_FULL_HOST" | ||
echo "!!! MULTIPLEX SSH CONNECTION ESTABLISHED !!!" | ||
|
||
set -x | ||
rsync --rsh="ssh -v -p 22 -i ${WPE_SSHG_KEY_PRIVATE_PATH} -o StrictHostKeyChecking=no -o 'ControlPath=$SSH_PATH/ctl/%C'" "${FLAGS_ARRAY[@]}" --exclude-from='/exclude.txt' --chmod=D775,F664 "${SRC_PATH}" "${WPE_DESTINATION}" | ||
rsync --rsh="ssh -v -p 22 -i ${WPE_SSHG_KEY_PRIVATE_PATH} -o StrictHostKeyChecking=no -o 'ControlPath=$SSH_PATH/ctl/%C'" "${FLAGS_ARRAY[@]}" --exclude-from=<( { { set +x; } 2>/dev/null; echo "$exclude_from"; } ) --chmod=D775,F664 "${SRC_PATH}" "${WPE_DESTINATION}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a block inside the process substitution and disabling debug mode prevents unwanted output. Sending errors to /dev/null
also prevents ++ set +x
from being added to the output.
The result is debugging output that is identical to how it was previously (with the exception of --exclude-from=/dev/fd/63
, which is referring to the temp file path created by the process substitution).
exclude-from.sh
Outdated
case "$REMOTE_PATH" in | ||
"wp-content") | ||
base_path="" | ||
mu_dir_path="mu-plugins/" | ||
;; | ||
"wp-content/mu-plugins") | ||
base_path="" | ||
mu_dir_path="" | ||
;; | ||
esac |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check me on this, but I believe these represent the only cases in which we would need to modify the paths.
If the user is deploying to other expected directories (eg, wp-content/plugins
or wp-content/themes
), the full relative paths are included.
While the above has no negative effect, we could consider further modifying the excludes list at that point to completely remove the WP and WPE-specific file paths. I did consider implementing that, but it felt a bit like overkill 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if wp-content/
and wp-content/mu-plugins
(/
appended) should also be matched 🤔
It seems like the deploy would likely work with either as the REMOTE_PATH
, so those might need to be added for comparison here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To-do: test with and without appended slash for REMOTE_PATH.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To-do: test with rsync destructive mode to confirm excludes work from the other direction (remote to local). Might mostly refer to a need for a new test case.
exclude-from.sh
Outdated
{ | ||
IFS= read -r base_path | ||
IFS= read -r mu_dir_path | ||
} <<< "$(determine_exclude_paths)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a shorthand approach for assigning local variables that respect ""
as a valid value.
In other words, calling read -r base_path mu_dir_path "$(determine_exclude_paths)"
can overwrite the first value with the second if only the first value will be evaluated as ""
.
tests/test_exclude_from.sh
Outdated
test_rsync_with_excludes() { | ||
export REMOTE_PATH=$1 | ||
echo -e "${BLUE}--- REMOTE_PATH: '$REMOTE_PATH'${NC}" | ||
|
||
local exclude_from; exclude_from="$(generate_exclude_from)" | ||
local fixture_path="$SCRIPT_DIR/data" | ||
|
||
# Capture the output of the rsync command | ||
output=$(rsync --dry-run --verbose --recursive --exclude-from=<(echo "$exclude_from") "$fixture_path" .) | ||
|
||
# Check if the output contains the expected file | ||
if echo "$output" | grep -q "test-plugin.php"; then | ||
echo -e "${GREEN}Test passed for rsync syncing files: test-plugin.php included.${NC}" | ||
else | ||
echo -e "${RED}Test failed for rsync syncing files: test-plugin.php excluded.${NC}" | ||
fi | ||
|
||
# Check that the output does not contain the excluded file | ||
if echo "$output" | grep -q "mu-plugin.php"; then | ||
echo -e "${RED}Test failed for rsync parsing excludes: mu-plugin.php included.${NC}" | ||
else | ||
echo -e "${GREEN}Test passed for rsync parsing excludes: mu-plugin.php excluded.${NC}" | ||
fi | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is very simplistic, it confirms that basic includes/excludes are working as expected with this new implementation and rsync.
Further testing of entrypoint
can be much more thorough when we have stubbing figured out.
39787b5
to
3351cbd
Compare
Also moves common.sh to new utils dir.
Also moves common.sh to new utils dir.
Include a dockerfile for test image
Closed in favor of #42 |
JIRA Ticket
CICD-761
Bug description
Customer reports that mu-plugins are being deleted when deploying with the GitHub Action. The plugins that are mentioned as being deleted are already part of our global excludes list in wpengine/site-deploy.
Reported in: wpengine/github-action-wpe-site-deploy#91
Background
We worked through several options for this ticket before landing on this implementation.
In #37, we tried forcing files to adhere to a specific structure expected by the remote target (making a relative remote), but felt the approach ended up being a bit risky with re-writing directory structure on each sync.
In #39, we tried removing relative path prepending in the exclude.txt file, but the approach was deemed a risk for affecting users that deploy to the root directory of a site (the paths in exclude.txt were treated like globs, meaning custom files could be unintentionally excluded).
The approach outlined below came up while solutioning in a review session, and we believe it is another good long-term option that reduces such risks.
What Are We Doing Here
This approach creates a excludes list for rsync on the fly, with the path for files in the excludes list inferred from the
REMOTE_PATH
environment variable.No exclude.txt is created — instead, the list is output to stdout before being used in a process substitution. This provides a temp file rsync can consume before it is destroyed at the end of the process.