Invalid version breaks registry for composer
Summary
Composer 2 cannot consume packages published with a version .x-dev suffix.
Note: according to comments, this also applies to composer 1.
Steps to reproduce
- make a branch called
1.5-composer-test - publish this branch into the composer registry
What is the current bug behavior?
This will create a package with version 1.5-composer-test.x-dev.
Trying to install any version of this package from this registry with composer 2 now results in:
[UnexpectedValueException]
Invalid version string "1.5-composer-test.x-dev"
What is the expected correct behavior?
I can use packages from this registry.
Workarounds
- manually remove all invalid versions from your registry
- to prevent creating invalid versions in the future, constrain publishing packages to valid versions:
publish:
stage: deploy
dependencies: []
rules:
- if: '$CI_COMMIT_TAG =~ /^v?\d+([.]\d+){2}(-(patch|p|alpha|a|beta|b|RC)\d*)?$/'
variables:
DATA: 'tag=$CI_COMMIT_TAG'
- if: $CI_COMMIT_TAG
when: never
- if: '$CI_COMMIT_REF_NAME =~ /^(v?(\d+)([.](\d+|[xX*]))*|v?\D.*)$/'
variables:
DATA: 'branch=$CI_COMMIT_REF_NAME'
cache: {}
before_script: []
variables:
# yamllint disable-line rule:line-length
URL: '$CI_SERVER_PROTOCOL://$CI_SERVER_HOST:$CI_SERVER_PORT/api/v4/projects/$CI_PROJECT_ID/packages/composer?job_token=$CI_JOB_TOKEN'
script:
- insecure=$([ "$CI_SERVER_PROTOCOL" = "http" ] && echo "--insecure" || echo "")
- response=$(curl -s -w "\n%{http_code}" $insecure --data "$DATA" $URL)
- code=$(echo "$response" | tail -n 1)
- body=$(echo "$response" | head -n 1)
# Output state information
- if [ $code -eq 201 ]; then
echo "Package created - Code $code - $body";
else
echo "Could not create package - Code $code - $body";
exit 1;
fi
Possible fixes
See the documentation:
When branch names look like versions, we have to clarify for composer that we're trying to check out a branch and not a tag. In the above example, we have two version branches: v1 and v2. To get Composer to check out one of these branches, you must specify a version constraint that looks like this: v1.x-dev. The .x is an arbitrary string that Composer requires to tell it that we're talking about the v1 branch and not a v1 tag (alternatively, you can name the branch v1.x instead of v1). In the case of a branch with a version-like name (v1, in this case), you append -dev as a suffix, rather than using dev- as a prefix.
IFAIU, this is saying that only branches that exactly look like versions should be treated with a -dev suffix. So, in this case the -composer-test part rules that branch name out of this case and hence it should be treated with a dev- prefix instead.
// a branch ending with -dev is only valid if it is numeric // if it gets prefixed with dev- it means the branch name should // have had a dev- prefix already when passed to normalize