Skip to content
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

Revert changes in vendor directory to fix SVN error #55

Merged
merged 4 commits into from
Jan 4, 2024

Conversation

ravinderk
Copy link
Contributor

@ravinderk ravinderk commented Jan 3, 2024

Description of the Change

Multiple times when using this Action we've run into issues where trying to push out changes to the readme.txt file doesn't work due to Other files have been modified; changes not deployed.

If you have a plugin that uses composer to install non-dev dependencies (or use it for the autoloader), when running this Action, you'll typically run composer install --no-dev as part of a build step. Composer will use a hash for some of the function names and this hash may change each time things are built.

When this Action compares the files from the SVN repo to what is in Github, those composer generated files don't match up due to these different hash values, resulting in the above error.

I figured out we can fix this issue by ignoring changes in vendor/composer and vendor/autoload.php.

Closes #49

How to test the Change

I am not sure if there's a best practice for how to test things here without accidentally deploying things to the .org SVN repo but here are the steps I took that others can follow:

  1. Checkout this branch develop branch.
  2. In the deploy.sh file, comment out lines 11-14 and 16-19. These lines deal with setting the svn username and password, which we don't want to do to avoid accidentally committing changes.
  3. Add the following line on line 20
     SLUG='ad-refresh-control'
     GITHUB_WORKSPACE='/Users/user/Downloads/ad-refresh-control'
    
     rm -rf '/Users/user/archivetmp';
    This code will remove the already created directory from the root directory which is generated upon running deploy.sh.
  4. In the deploy.sh file, comment out lines 114-116. These lines deal with syncing assets in the svn directory.
  5. In the deploy.sh file, comment out lines 188-199. These lines are what actually commit the changes. They shouldn't work without a proper username and password but I feel better removing those
  6. Clone a plugin (ad-refresh-control) that uses composer and runs whatever production build steps this plugin needs. The goal is to end up with a plugin built the same way you would before deploying it to .org
  7. Then run the script: ./deploy.sh. You should get an error about other files being modified and right above that line, you should see some vendor directories being flagged
    image
  8. Checkout this branch feat/auto-ignore-vendor-directory branch.
  9. Run ./deploy.sh again. You should get a message saying Nothing to deploy! or other but right above that you should see lines about reverting the vendor directory
    image
    image
This is the deploy.sh script that I used for testing.
#!/bin/bash

# Note that this does not use pipefail because if the grep later
# doesn't match I want to be able to show an error first
set -eo

# Ensure SVN username and password are set
# IMPORTANT: while secrets are encrypted and not viewable in the GitHub UI,
# they are by necessity provided as plaintext in the context of the Action,
# so do not echo or use debug mode unless you want your secrets exposed!
# if [[ -z "$SVN_USERNAME" ]]; then
# 	echo "Set the SVN_USERNAME secret"
# 	exit 1
# fi

# if [[ -z "$SVN_PASSWORD" ]]; then
# 	echo "Set the SVN_PASSWORD secret"
# 	exit 1
# fi

SLUG='ad-refresh-control'
GITHUB_WORKSPACE='/Users/********/Local-Sites/10osp/app/public/wp-content/plugins/ad-refresh-control'

rm -rf '/Users/*******/archivetmp';

# Allow some ENV variables to be customized
if [[ -z "$SLUG" ]]; then
	SLUG=${GITHUB_REPOSITORY#*/}
fi
echo "ℹ︎ SLUG is $SLUG"

if [[ -z "$ASSETS_DIR" ]]; then
	ASSETS_DIR=".wordpress-org"
fi
echo "ℹ︎ ASSETS_DIR is $ASSETS_DIR"

if [[ -z "$README_NAME" ]]; then
	README_NAME="readme.txt"
fi
echo "ℹ︎ README_NAME is $README_NAME"

if [[ -z "$IGNORE_OTHER_FILES" ]]; then
	IGNORE_OTHER_FILES=false
fi
echo "ℹ︎ IGNORE_OTHER_FILES is $IGNORE_OTHER_FILES"

SVN_URL="https://plugins.svn.wordpress.org/${SLUG}/"
SVN_DIR="${HOME}/svn-${SLUG}"

# Checkout just trunk and assets for efficiency
# Stable tag will come later, if applicable
echo "➤ Checking out .org repository..."
svn checkout --depth immediates "$SVN_URL" "$SVN_DIR"
cd "$SVN_DIR"
svn update --set-depth infinity assets
svn update --set-depth infinity trunk

echo "➤ Copying files..."
if [ "$IGNORE_OTHER_FILES" = true ]; then
	# Copy readme.txt to /trunk
	cp "$GITHUB_WORKSPACE/$README_NAME" trunk/$README_NAME

	# Use $TMP_DIR as the source of truth
	TMP_DIR=$GITHUB_WORKSPACE
else
	if [[ -e "$GITHUB_WORKSPACE/.distignore" ]]; then
		echo "ℹ︎ Using .distignore"

		# Use $TMP_DIR as the source of truth
		TMP_DIR=$GITHUB_WORKSPACE

		# Copy from current branch to /trunk, excluding dotorg assets
		# The --delete flag will delete anything in destination that no longer exists in source
		rsync -rc --exclude-from="$GITHUB_WORKSPACE/.distignore" "$GITHUB_WORKSPACE/" trunk/ --delete --delete-excluded
	else
		echo "ℹ︎ Using .gitattributes"

		cd "$GITHUB_WORKSPACE"

		# "Export" a cleaned copy to a temp directory
		TMP_DIR="${HOME}/archivetmp"
		mkdir "$TMP_DIR"

		git config --global user.email "[email protected]"
		git config --global user.name "10upbot on GitHub"

		# If there's no .gitattributes file, write a default one into place
		if [[ ! -e "$GITHUB_WORKSPACE/.gitattributes" ]]; then
			cat > "$GITHUB_WORKSPACE/.gitattributes" <<-EOL
			/$ASSETS_DIR export-ignore
			/.gitattributes export-ignore
			/.gitignore export-ignore
			/.github export-ignore
			EOL

			# Ensure we are in the $GITHUB_WORKSPACE directory, just in case
			# The .gitattributes file has to be committed to be used
			# Just don't push it to the origin repo :)
			git add .gitattributes && git commit -m "Add .gitattributes file"
		fi

		# This will exclude everything in the .gitattributes file with the export-ignore flag
		git archive HEAD | tar x --directory="$TMP_DIR"

		cd "$SVN_DIR"

		# Copy from clean copy to /trunk, excluding dotorg assets
		# The --delete flag will delete anything in destination that no longer exists in source
		rsync -rc "$TMP_DIR/" trunk/ --delete --delete-excluded
	fi
fi

# Do not sync assets if SKIP_ASSETS set to true
# if [[ "$SKIP_ASSETS" != "true" ]]; then
#      rsync -rc "$GITHUB_WORKSPACE/$ASSETS_DIR/" assets/ --delete --delete-excluded
# fi

# Fix screenshots getting force downloaded when clicking them
# https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/
if test -d "$SVN_DIR/assets" && test -n "$(find "$SVN_DIR/assets" -maxdepth 1 -name "*.png" -print -quit)"; then
    svn propset svn:mime-type "image/png" "$SVN_DIR/assets/"*.png || true
fi
if test -d "$SVN_DIR/assets" && test -n "$(find "$SVN_DIR/assets" -maxdepth 1 -name "*.jpg" -print -quit)"; then
    svn propset svn:mime-type "image/jpeg" "$SVN_DIR/assets/"*.jpg || true
fi
if test -d "$SVN_DIR/assets" && test -n "$(find "$SVN_DIR/assets" -maxdepth 1 -name "*.gif" -print -quit)"; then
    svn propset svn:mime-type "image/gif" "$SVN_DIR/assets/"*.gif || true
fi
if test -d "$SVN_DIR/assets" && test -n "$(find "$SVN_DIR/assets" -maxdepth 1 -name "*.svg" -print -quit)"; then
    svn propset svn:mime-type "image/svg+xml" "$SVN_DIR/assets/"*.svg || true
fi

echo "➤ Preparing files..."

# Revert changes in vendor directory in trunk.
# This is needed because composer dynamically generates files using hashing.
# In reality, the files are not changed, but SVN thinks they are and throws an error.

# Check if vendor/composer has changes
if [[ -n $(svn stat trunk/vendor/composer) ]]; then
    svn revert --depth=infinity trunk/vendor/composer
fi

# Check if vendor/autoload.php has changes
if [[ -n $(svn stat trunk/vendor/autoload.php) ]]; then
    svn revert trunk/vendor/autoload.php
fi

svn status

if [[ -z $(svn stat) ]]; then
	echo "🛑 Nothing to deploy!"
	exit 0
# Check if there is more than just the readme.txt modified in trunk
# The leading whitespace in the pattern is important
# so it doesn't match potential readme.txt in subdirectories!
elif svn stat trunk | grep -qvi " trunk/$README_NAME$"; then
	echo "🛑 Other files have been modified; changes not deployed"
	exit 1
fi

# Readme also has to be updated in the .org tag
echo "➤ Preparing stable tag..."
STABLE_TAG=$(grep -m 1 -E "^([*+-]\s+)?Stable tag:" "$TMP_DIR/$README_NAME" | tr -d '\r\n' | awk -F ' ' '{print $NF}')

if [[ -z "$STABLE_TAG" ]]; then
    echo "ℹ︎ Could not get stable tag from $README_NAME";
else
	echo "ℹ︎ STABLE_TAG is $STABLE_TAG"

	if svn info "^/$SLUG/tags/$STABLE_TAG" > /dev/null 2>&1; then
		svn update --set-depth infinity "tags/$STABLE_TAG"

		# Not doing the copying in SVN for the sake of easy history
		rsync -c "$TMP_DIR/$README_NAME" "tags/$STABLE_TAG/"
	else
		echo "ℹ︎ Tag $STABLE_TAG not found"
	fi
fi

# Add everything and commit to SVN
# The force flag ensures we recurse into subdirectories even if they are already added
# Suppress stdout in favor of svn status later for readability
svn add . --force > /dev/null

# SVN delete all deleted files
# Also suppress stdout here
# svn status | grep '^\!' | sed 's/! *//' | xargs -I% svn rm %@ > /dev/null

# #Resolves => SVN commit failed: Directory out of date
# svn update

# # Now show full SVN status
# svn status

# echo "➤ Committing files..."
# svn commit -m "Updating readme/assets from GitHub" --no-auth-cache --non-interactive  --username "$SVN_USERNAME" --password "$SVN_PASSWORD"

# echo "✓ Plugin deployed!"

Changelog Entry

Added - Ignore changes to the vendor/composer directory and vendor/autoload.php to prevent SVN error.

Credits

Props @dkotter, @cadic @ravinderk

Checklist:

  • I agree to follow this project's Code of Conduct.
  • I have updated the documentation accordingly.
  • I have added tests to cover my change.
  • All new and existing tests pass.

@ravinderk ravinderk requested a review from dkotter January 3, 2024 14:30
@ravinderk ravinderk self-assigned this Jan 3, 2024
@ravinderk ravinderk marked this pull request as ready for review January 3, 2024 14:32
@ravinderk ravinderk requested a review from a team as a code owner January 3, 2024 14:32
@jeffpaul jeffpaul added this to the 2.2.0 milestone Jan 3, 2024
@dkotter dkotter modified the milestones: 2.2.0, 2.1.3 Jan 4, 2024
@dkotter dkotter merged commit d143f0d into develop Jan 4, 2024
1 check passed
@dkotter dkotter deleted the feat/auto-ignore-vendor-directory branch January 4, 2024 20:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Composer autoloader considered as "Other files have been modified"
3 participants