Skip to content

Commit df1f8e3

Browse files
authored
Merge pull request #10 from valicm/9-fix-full-mode-upgrade
Fix full upgrade mode. Split core and contrib processing. Run core as last
2 parents 8939240 + b7cfadb commit df1f8e3

File tree

2 files changed

+147
-111
lines changed

2 files changed

+147
-111
lines changed

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ inputs:
1010
required: false
1111
default: 'semver-safe-update'
1212
update_core:
13-
description: 'Skip checking for Drupal core updates. Default false'
13+
description: 'Skip checking for Drupal core updates. Default true'
1414
required: false
1515
default: 'true'
1616
update_exclude:

drupal-update.sh

Lines changed: 146 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ validate_requirements() {
7070
fi
7171

7272
local BINARIES="php composer sed grep jq";
73+
local BINARY
7374
for BINARY in $BINARIES
7475
do
7576
if ! [ -x "$(command -v "$BINARY")" ]; then
@@ -80,57 +81,139 @@ validate_requirements() {
8081

8182
}
8283

83-
# Update project based on composer update status.
84-
# Mark dev versions as a success because we don't have a specific version.
85-
update_project() {
86-
PROJECT_NAME=$1
87-
CURRENT_VERSION=$2
88-
LATEST_VERSION=$3
89-
UPDATE_STATUS=$4
90-
PATCH_LIST=$5
91-
local COMPOSER_OUTPUT=
84+
# Handles output from Composer, and assign corresponding status.
85+
composer_output() {
86+
local COMPOSER_OUTPUT
87+
local PROJECT_NAME
88+
local LATEST_VERSION
89+
local UPDATE_STATUS
90+
local PATCH_LIST
91+
PROJECT_NAME=$1
92+
LATEST_VERSION=$2
93+
UPDATE_STATUS=$3
94+
PATCH_LIST=$4
95+
96+
# Handle specific case for Drupal core.
97+
if [ "$PROJECT_NAME" = "drupal/core" ]; then
98+
if [ "$UPDATE_TYPE" == "all" ] && [ "$UPDATE_STATUS" == "update-possible" ]; then
99+
COMPOSER_OUTPUT=$(composer require drupal/core-recommended:"$LATEST_VERSION" drupal/core-composer-scaffold:"$LATEST_VERSION" drupal/core-project-message:"$LATEST_VERSION" -W -q -n --ignore-platform-reqs)
100+
else
101+
COMPOSER_OUTPUT=$(composer update drupal/core-* -W -q -n --ignore-platform-reqs)
102+
fi
103+
else
92104
if [ "$UPDATE_STATUS" == "update-possible" ]; then
93105
COMPOSER_OUTPUT=$(composer require "$PROJECT_NAME":"$LATEST_VERSION" -W -q -n --ignore-platform-reqs)
94106
else
95107
COMPOSER_OUTPUT=$(composer update "$PROJECT_NAME" -W -q -n --ignore-platform-reqs)
96108
fi
109+
fi
110+
111+
local EXIT_CODE=$?;
112+
113+
case "$EXIT_CODE" in
114+
0)
115+
echo $RESULT_SUCCESS
116+
;;
117+
1)
118+
local RESULT
119+
# Do a sanity check before comparing patches.
120+
if [[ $LATEST_VERSION == dev-* ]]; then
121+
RESULT=$RESULT_SUCCESS
122+
elif grep -q "$LATEST_VERSION" composer.lock; then
123+
RESULT=$RESULT_SUCCESS
124+
else
125+
RESULT=$RESULT_GENERIC_ERROR
126+
fi
127+
128+
# Compare the list of patches. We need to compare them because if previous
129+
# one failed; composer install is going to throw an error.
130+
if [ -n "$PATCH_LIST" ]; then
131+
local PATCH=
132+
for PATCH in $(echo "${PATCH_LIST}" | jq -c '.[]'); do
133+
if [ "$(grep -s -c -ic "$PATCH" "$COMPOSER_OUTPUT")" != 0 ]; then
134+
RESULT="$PATCH"
135+
else
136+
continue
137+
fi
138+
done
139+
fi
140+
echo "$RESULT"
141+
;;
142+
2)
143+
echo "$RESULT_DEPENDENCY_ERROR"
144+
;;
145+
*)
146+
echo "$RESULT_UNKNOWN"
147+
esac
148+
}
149+
150+
# Update or skip project per different criteria.
151+
update_project() {
152+
local COMPOSER_PACKAGE=$1
153+
declare -n RESULT_TABLE=$2
154+
declare -n RESULT_HIGHLIGHTS=$3
155+
local RESULT_STATUS=$RESULT_SKIP
156+
local SKIP_PROJECT=false
157+
local PROJECT_NAME
158+
local PROJECT_URL
159+
local CURRENT_VERSION
160+
local LATEST_VERSION
161+
local UPDATE_STATUS
162+
local ABANDONED
163+
local PATCHES
164+
PROJECT_NAME=$(echo "${COMPOSER_PACKAGE}" | jq '."name"' | sed "s/\"//g")
165+
PROJECT_URL=$(echo "${COMPOSER_PACKAGE}" | jq '."homepage"' | sed "s/\"//g")
166+
if [ -z "$PROJECT_URL" ] || [ "$PROJECT_URL" == null ]; then
167+
PROJECT_URL="https://www.drupal.org/project/drupal"
168+
fi
169+
CURRENT_VERSION=$(echo "${COMPOSER_PACKAGE}" | jq '."version"' | sed "s/\"//g")
170+
LATEST_VERSION=$(echo "${COMPOSER_PACKAGE}" | jq '."latest"' | sed "s/\"//g")
171+
UPDATE_STATUS=$(echo "${COMPOSER_PACKAGE}" | jq '."latest-status"' | sed "s/\"//g")
172+
ABANDONED=$(echo "${COMPOSER_PACKAGE}" | jq '."abandoned"' | sed "s/\"//g")
173+
PATCHES=$(echo "$COMPOSER_CONTENTS" | jq '.extra.patches."'"$PROJECT_NAME"'" | length')
174+
175+
local PATCH_LIST=
176+
if [ "$PATCHES" -gt 0 ]; then
177+
PATCH_LIST=$(echo "$COMPOSER_CONTENTS" | jq '.extra.patches."'"$PROJECT_NAME"'"')
178+
fi
179+
180+
local PROJECT_RELEASE_URL=$PROJECT_URL
181+
if [[ $LATEST_VERSION != dev-* ]]; then
182+
PROJECT_RELEASE_URL=$PROJECT_URL"/releases/"$LATEST_VERSION
183+
fi
184+
185+
# Go through excluded packages and skip them.
186+
if [ -n "$UPDATE_EXCLUDE" ]; then
187+
local EXCLUDE=
188+
for EXCLUDE in $UPDATE_EXCLUDE
189+
do
190+
if [ "$PROJECT_NAME" == "drupal/$EXCLUDE" ]; then
191+
echo "Skipping upgrades for $PROJECT_NAME"
192+
SKIP_PROJECT=true
193+
fi
194+
done
195+
fi
196+
197+
if [ "$UPDATE_TYPE" != "all" ] && [ "$UPDATE_STATUS" != "$UPDATE_TYPE" ]; then
198+
echo "Skipping upgrades for $PROJECT_NAME"
199+
SKIP_PROJECT=true
200+
fi
201+
202+
if [ $SKIP_PROJECT == false ]; then
203+
echo "Update $PROJECT_NAME from $CURRENT_VERSION to $LATEST_VERSION"
204+
RESULT_STATUS=$(composer_output "$PROJECT_NAME" "$LATEST_VERSION" "$UPDATE_STATUS" "$PATCH_LIST")
205+
# Write specific cases in the highlights summary report.
206+
if [ ${#RESULT_STATUS} -gt 20 ]; then
207+
RESULT_HIGHLIGHTS+="- **$PROJECT_NAME** have failed to apply a patch: *$RESULT_STATUS*.\n"
208+
RESULT_STATUS=$RESULT_PATCH_FAILURE
209+
fi
97210

98-
local EXIT_CODE=$?;
99-
100-
case "$EXIT_CODE" in
101-
0)
102-
echo $RESULT_SUCCESS
103-
;;
104-
1)
105-
# Do a sanity check before comparing patches.
106-
if [[ $LATEST_VERSION == dev-* ]]; then
107-
RESULT=$RESULT_SUCCESS
108-
elif grep -q "$LATEST_VERSION" composer.lock; then
109-
RESULT=$RESULT_SUCCESS
110-
else
111-
RESULT=$RESULT_GENERIC_ERROR
112-
fi
113-
114-
# Compare the list of patches. We need to compare them because if previous
115-
# one failed; composer install is going to throw an error.
116-
if [ -n "$PATCH_LIST" ]; then
117-
local PATCH=
118-
for PATCH in $(echo "${PATCH_LIST}" | jq -c '.[]'); do
119-
if [ "$(grep -s -c -ic "$PATCH" "$COMPOSER_OUTPUT")" != 0 ]; then
120-
RESULT="$PATCH"
121-
else
122-
continue
123-
fi
124-
done
125-
fi
126-
echo "$RESULT"
127-
;;
128-
2)
129-
echo "$RESULT_DEPENDENCY_ERROR"
130-
;;
131-
*)
132-
echo "$RESULT_UNKNOWN"
133-
esac
211+
if [ "$RESULT_STATUS" == "$RESULT_DEPENDENCY_ERROR" ]; then
212+
RESULT_HIGHLIGHTS+="- **$PROJECT_NAME** have an unresolved dependency.\n"
213+
fi
214+
fi
215+
# Write entry for all cases.
216+
RESULT_TABLE+="| [${PROJECT_NAME}](${PROJECT_URL}) | ${CURRENT_VERSION} | [${LATEST_VERSION}]($PROJECT_RELEASE_URL) | $RESULT_STATUS | $PATCHES | $ABANDONED |\n"
134217
}
135218

136219
# Set default values.
@@ -198,75 +281,28 @@ SUMMARY_OUTPUT_TABLE+="| ------ | ------ | ------ | ------ | ------ | ------ |\n
198281
# Read composer output. Remove whitespaces - jq 1.5 can break while parsing.
199282
UPDATES=$(composer outdated "drupal/*" -f json -D --locked --ignore-platform-reqs | sed -r 's/\s+//g');
200283

201-
for UPDATE in $(echo "${UPDATES}" | jq -c '.locked[]'); do
202-
PROJECT_NAME=$(echo "${UPDATE}" | jq '."name"' | sed "s/\"//g")
203-
PROJECT_URL=$(echo "${UPDATE}" | jq '."homepage"' | sed "s/\"//g")
204-
if [ -z "$PROJECT_URL" ] || [ "$PROJECT_URL" == null ]; then
205-
PROJECT_URL="https://www.drupal.org/project/drupal"
206-
fi
207-
CURRENT_VERSION=$(echo "${UPDATE}" | jq '."version"' | sed "s/\"//g")
208-
LATEST_VERSION=$(echo "${UPDATE}" | jq '."latest"' | sed "s/\"//g")
209-
UPDATE_STATUS=$(echo "${UPDATE}" | jq '."latest-status"' | sed "s/\"//g")
210-
ABANDONED=$(echo "${UPDATE}" | jq '."abandoned"' | sed "s/\"//g")
211-
PATCHES=$(echo "$COMPOSER_CONTENTS" | jq '.extra.patches."'"$PROJECT_NAME"'" | length')
212-
213-
PATCH_LIST=
214-
if [ "$PATCHES" -gt 0 ]; then
215-
PATCH_LIST=$(echo "$COMPOSER_CONTENTS" | jq '.extra.patches."'"$PROJECT_NAME"'"')
216-
fi
217-
218-
PROJECT_RELEASE_URL=$PROJECT_URL
219-
if [[ $LATEST_VERSION != dev-* ]]; then
220-
PROJECT_RELEASE_URL=$PROJECT_URL"/releases/"$LATEST_VERSION
221-
fi
222-
223-
RESULT=$RESULT_SKIP
224-
225-
# Go through excluded packages and skip them.
226-
if [ -n "$UPDATE_EXCLUDE" ]; then
227-
for EXCLUDE in $UPDATE_EXCLUDE
228-
do
229-
if [ "$PROJECT_NAME" == "drupal/$EXCLUDE" ]; then
230-
SUMMARY_OUTPUT_TABLE+="| [${PROJECT_NAME}](${PROJECT_URL}) | ${CURRENT_VERSION} | [${LATEST_VERSION}]($PROJECT_RELEASE_URL) | $RESULT | $PATCHES | $ABANDONED |\n"
231-
continue
232-
fi
233-
done
234-
fi
235-
236-
# If we need to skip Drupal core updates.
237-
# Still write the latest version for the summary table.
238-
if [ "$UPDATE_CORE" == false ]; then
239-
if [[ "$PROJECT_NAME" =~ drupal/core-* ]] || [ "$PROJECT_NAME" = "drupal/core" ]; then
240-
echo "Skipping upgrades for $PROJECT_NAME"
241-
SUMMARY_OUTPUT_TABLE+="| [${PROJECT_NAME}](${PROJECT_URL}) | ${CURRENT_VERSION} | [${LATEST_VERSION}]($PROJECT_RELEASE_URL) | $RESULT | $PATCHES | $ABANDONED |\n"
242-
continue
243-
fi
244-
fi
245-
246-
if [ "$UPDATE_TYPE" == 'all' ]; then
247-
echo "Update $PROJECT_NAME from $CURRENT_VERSION to $LATEST_VERSION"
248-
RESULT=$(update_project "$PROJECT_NAME" "$CURRENT_VERSION" "$LATEST_VERSION" "$UPDATE_STATUS", "$PATCH_LIST")
249-
else
250-
if [ "$UPDATE_STATUS" == "$UPDATE_TYPE" ]; then
251-
echo "Update $PROJECT_NAME from $CURRENT_VERSION to $LATEST_VERSION"
252-
RESULT=$(update_project "$PROJECT_NAME" "$CURRENT_VERSION" "$LATEST_VERSION" "$UPDATE_STATUS", "$PATCH_LIST")
253-
else
254-
echo "Skipping upgrades for $PROJECT_NAME"
255-
fi
284+
# Loop trough other packages.
285+
for UPDATE_PACKAGE in $(echo "${UPDATES}" | jq -c '.locked[]'); do
286+
PROJECT_NAME=$(echo "${UPDATE_PACKAGE}" | jq '."name"' | sed "s/\"//g")
287+
# Skip all core packages. Perform core upgrades as last one.
288+
if [[ "$PROJECT_NAME" = drupal/core-* ]] || [ "$PROJECT_NAME" = "drupal/core" ]; then
289+
continue
256290
fi
291+
update_project "$UPDATE_PACKAGE" SUMMARY_OUTPUT_TABLE SUMMARY_INSTRUCTIONS
292+
done
257293

258-
# Write specific cases in the highlights summary report.
259-
if [ ${#RESULT} -gt 20 ]; then
260-
SUMMARY_INSTRUCTIONS+="- **$PROJECT_NAME** had failed to apply a patch: *$RESULT*.\n"
261-
RESULT=$RESULT_PATCH_FAILURE
294+
# If we have core updates enabled, these needs to run last in ideal case.
295+
# It is not going through work for 99.99% of 9.5 to 10 installations.
296+
# It should be passable between same major versions of D10.
297+
if [ "$UPDATE_CORE" == true ]; then
298+
CORE_PACKAGE=$(echo "${UPDATES}" | jq -c '.locked[] | select(.name == "drupal/core")')
299+
if [ -z "$CORE_PACKAGE" ] || [ "$CORE_PACKAGE" == null ]; then
300+
CORE_PACKAGE=$(echo "${UPDATES}" | jq -c '.locked[] | select(.name == "drupal/core-recommended")')
262301
fi
263-
264-
if [ "$RESULT" == "$RESULT_DEPENDENCY_ERROR" ]; then
265-
SUMMARY_INSTRUCTIONS+="- **$PROJECT_NAME** had an unresolved dependency.\n"
302+
if [ "$CORE_PACKAGE" ]; then
303+
update_project "$CORE_PACKAGE" SUMMARY_OUTPUT_TABLE SUMMARY_INSTRUCTIONS
266304
fi
267-
268-
SUMMARY_OUTPUT_TABLE+="| [${PROJECT_NAME}](${PROJECT_URL}) | ${CURRENT_VERSION} | [${LATEST_VERSION}]($PROJECT_RELEASE_URL) | $RESULT | $PATCHES | $ABANDONED |\n"
269-
done
305+
fi
270306

271307
SUMMARY_INSTRUCTIONS+="\n$SUMMARY_OUTPUT_TABLE"
272308

0 commit comments

Comments
 (0)