message:
Extend Alternatives section, minor fixes
One of goals was bit reworded
Rephrase comments for CloudControllerManagerMode constants
Fix types in `API Extensions` section

diff:
@@ -104,7 +104,7 @@ without the necessity of tying to Red Hat's internal processes or keeping a fork
- Remove the necessity to make changes in "openshift/api", "openshift/library-go" and dependant infrastructure-related components during basic cloud-provider integration with OpenShift
- Make a cloud provider integration process more accessible and simple to external contributors as well as for RH engineers
- Provide an overview of projected changes to affected components that will be planned for a later phase of development
-- Introduce a somewhat "neutral" platform type, which would serve as a signal about an underlying, but generic, cloud-provider presence
+- Introduce a somewhat "neutral" platform type, which would serve as a signal about an underlying generic cloud-provider presence
### Non-Goals
@@ -301,7 +301,7 @@ and, in theory, in the future, it might be extended in a way to react to the new
platform-specific credentials management logic.
During initial enablement phases of "External" platform type, no specific actions will be needed there, since
-CCO [would](https://github.com/openshift/cloud-credential-operator/blob/master/pkg/operator/controller.go#L134) go
+CCO [would](https://github.com/openshift/cloud-credential-operator/blob/58c41771a87e613415a1fa16d299601a1c2f48c2/pkg/operator/controller.go#L134) go
into no-op mode if it encounters an unrecognized platform.
#### Cluster Image Registry Operator
@@ -373,11 +373,11 @@ type CloudControllerManagerMode string
const (
// Cloud Controller Manager is enabled and expected to be supplied.
- // Signaling MCO to set `--cloud-provider=external` flag to the kubelets.
- CloudControllerManagerExternal CloudControllerManagerState = "External"
- // No Cloud Controller Manager is expected to be supplied.
- // Signaling MCO not to set `--cloud-provider` flag to the kubelets.
- CloudControllerManagerNone CloudControllerManagerState = "None"
+ // Signaling that kubelets and other CCM consumers should use --cloud-provider=external.
+ CloudControllerManagerExternal CloudControllerManagerMode = "External"
+ // Cloud Controller Manager is enabled and expected to be supplied.
+ // Signaling that kubelets and other CCM consumers should not set --cloud-provider flag.
+ CloudControllerManagerNone CloudControllerManagerMode = "None"
)
type CloudControllerManagerSettings struct {
@@ -551,9 +551,19 @@ TBD
## Alternatives
-Leave things as is, i.e. encode every new cloud platform statically into "openshift/api" from the beginning of a technical enablement process.
+Leave things as is, i.e., encode every new cloud platform statically into "openshift/api" from the beginning of a technical enablement process.
+
+### Proceed to use "None" Platform type
+
+We could proceed to leverage PlatformType "None"; however, there are some difficulties that need to be worked around somehow, some examples:
+
+* No defined mechanism to set `--cloud-provider=external` arg to kubelet/KCM/apiserver without merges and further revendoring of "openshift/api",
+ at the moment, decision-making here is tied to the PlatformType.
+ - This might be solved by creating additional documentation and mechanisms for propagating and controlling additional flags on kubelet/KCM/apiserver.
+ - Possible approach proposed in this EP, but an alternative API / mechanism is possible.
-Also, we could proceed to leverage PlatformType "None".
+* No way to extend machine-api and deliver a new provider without merges to "openshift/machine-api-operator" and "openshift/api" repos.
+ - This might be solved by teaching the MachineAPI operator to deploy platform-independent components despite a platform type.
## Infrastructure Needed

original_message:
Extend Alternatives section, minor fixes

- One of goals was bit reworded
- Rephrase comments for CloudControllerManagerMode constants
- Fix types in `API Extensions` section


message: Add section about the Windows Machine Config Operator

change_type: MODIFY

diff:
@@ -163,7 +163,7 @@ Given that PlatformSpec and PlatformStatus are defined as "discriminated unions"
"openshift/api" beforehand, it creates a significant footprint and plenty of effort from Red Hat engineers to create the initial technical enablement of
a new cloud provider and mostly impossible without Red Hat engineering engagement.
-Since a lot of infrastructure related components (such as [CCCMO](https://github.com/openshift/cluster-cloud-controller-manager-operator), [Machine API operator](https://github.com/openshift/machine-api-operator), [Machine Config Operator](https://github.com/openshift/machine-config-operator), and so on)
+Since a lot of infrastructure related components (such as [CCCMO](https://github.com/openshift/cluster-cloud-controller-manager-operator), [Machine API operator](https://github.com/openshift/machine-api-operator), [Machine Config Operator](https://github.com/openshift/machine-config-operator), [Windows Machine Config Operator](https://github.com/openshift/windows-machine-config-operator) and so on)
require information about, at least, the presence of an underlying cloud provider, the "None" platform does not fit well as a signal in such a situation.
A special, built-in, and somewhat generic platform type that will signal about the presence of an underlying infrastructure platform without
@@ -244,6 +244,22 @@ Then, down the road (during [phase 3](#implementation-phases)), it would be expe
For an explicit signal about the necessity to set `--cloud-provider=external` flag to the kubelet, we will use the `CloudControllerManager` field of the `ExternalPlatformSpec`, which is
described in the [API Extensions](#api-extensions) section down below.
+#### Windows Machine Config Operator
+
+The Windows Machine Config Operator configures Windows instances into nodes, enabling Windows container workloads to run within OCP clusters.
+
+Its behaviour relies on the [Machine Config Operator](#machine-config-operator) since Windows-related machinery uses MCO-rendered ignition files
+(there are plans to switch this to use MachineConfigs) to extract and then use some kubelet flags, including the `--cloud-provider` one.
+
+Initially, the new "External" platform should be treated similarly to PlatformType "None" by the WMCO.
+
+Important to note that WMCO has specific behaviour for the `None` platform type.
+With this platform type WMCO [will](https://github.com/openshift/windows-machine-config-operator/blob/95a2c5225a066f40fb4af44cbd5a4d4d763c149e/pkg/windows/windows.go#L654) [set](https://github.com/openshift/windows-machine-config-operator/blob/95a2c5225a066f40fb4af44cbd5a4d4d763c149e/pkg/windows/windows.go#L654)
+`--node-ip` flag with the user-provided IP address, which requires additional configuration.
+For other supported platform types, WMCO relies on MachineAPI to figure out IP addresses or does not set this flag at all.
+This seems acceptable for the initial phase, but during [phase 3](#implementation-phases) this behaviour should be revised and changed
+to provide users additional knobs to configure this behaviour or, perhaps, check MachineAPI engagement to make a decision.
+
#### Cluster Cloud Controller Manager Operator
Responsible for deploying platform-specific Cloud Controller Manager as well as for handling a number of OpenShift's

license: Apache License 2.0

repo: openshift/enhancements


message:
Update and cleanup wording
Update wording based on comments,
some phrases should look better now.

diff:
@@ -22,7 +22,7 @@ api-approvers:
- "@deads2k"
- "@JoelSpeed"
creation-date: 2022-09-06
-last-updated: 2022-09-23
+last-updated: 2022-10-25
tracking-link:
- https://issues.redhat.com/browse/OCPPLAN-9429
- https://issues.redhat.com/browse/OCPPLAN-8156
@@ -56,22 +56,22 @@ any core payload components and without the need for direct involvement of OpenS
## Motivation
Historically, the k8s project contained plenty of code for handling integration with
-various cloud providers (AWS, GCP, vSphere). These pieces were developed and released along with the k8s as a part of a core,
-however, over time, the community concluded that this approach does not scale and manages well and should be changed.
+various cloud providers (AWS, GCP, vSphere). These pieces were developed and released as part of Kubernetes core.
+However, over time, the community concluded that this approach does not scale well and should be changed.
The community put a lot of energy into introducing the [mechanism](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cloud-provider/2392-cloud-controller-manager) to allow cloud-providers and community members
to build, develop, test and release provider-specific components independently from the Kubernetes core.
-Speaking about the Openshift integrations with cloud providers - for the moment, a lot of things are tended to be encoded
-in [the Openshift codebase](https://docs.providers.openshift.org/cloud-controller-manager/#integrating-with-other-openshift-components)
-within API definitions, operators logic, and installer program code.
-This fact creates quite a lot of obstacles for RH partners and community members in their attempts to add new cloud providers to Openshift,
+With regard to OpenShift integrations with cloud providers, for the moment, a lot of things are tended to be encoded
+in [the OpenShift codebase](https://docs.providers.openshift.org/cloud-controller-manager/#integrating-with-other-openshift-components)
+within API definitions, operator logic, and installer program code.
+This fact creates quite a lot of obstacles for RH partners and community members in their attempts to add new cloud providers to OpenShift,
as well as making RH engineering involvement quite necessary.
-Lately, there have been several initiatives around making Openshift more composable and flexible,
-for example [Capabilites selection](https://github.com/openshift/enhancements/blob/master/enhancements/installer/component-selection.md) and
+Lately, there have been several initiatives around making OpenShift more composable and flexible.
+For example, [Capabilites selection](https://github.com/openshift/enhancements/blob/master/enhancements/installer/component-selection.md) and
[Platform Operators](https://github.com/openshift/enhancements/blob/master/enhancements/olm/platform-operators.md) are
-the significant steps towards this direction. However, despite having these powerful instruments, there is still necessary
-to land a code into the Openshift codebase for technical enablement of a new cloud provider, which might be hard or
+significant steps in this direction. However, despite having these powerful instruments, it is still necessary
+to land code into the OpenShift codebase for technical enablement of a new cloud provider, which might be hard or
nearly impossible for external contributors.
Imagine some regional or special-purpose cloud have created an infrastructure platform that resembles AWS but has its own API that is different than AWS.
@@ -81,12 +81,12 @@ and [platform operators](https://github.com/openshift/enhancements/blob/master/e
they can still deliver this functionality by creating their own Cloud Controller Managers,
CSI drivers, network topology operators, Machine API controllers, and OpenShift configurations.
This allows these cloud providers to supply the best OpenShift experience while also developing their components
-without the necessity of tying to Red Hat's internal processes or keeping a fork of the significant part of the Openshift code base.
+without the necessity of tying to Red Hat's internal processes or keeping a fork of the significant part of the OpenShift code base.
### User Stories
- As a cloud-provider affiliated engineer / platform integrator / RH partner
- I want to have a mechanism to signal Openshift's built-in operators about additional
+ I want to have a mechanism to signal OpenShift's built-in operators about additional
cloud-provider specific components so that I can inject my own platform-specific controllers into OpenShift
to improve the integration between OpenShift and my cloud provider.
@@ -101,10 +101,10 @@ without the necessity of tying to Red Hat's internal processes or keeping a fork
### Goals
-- Remove the necessity to make changes in "openshift/api", "openshift/library-go" and dependant infrastructure-related components during basic cloud-provider integration with OpenShift
-- Make a cloud provider integration process more accessible and simple to external contributors as well as for RH engineers
-- Provide an overview of projected changes to affected components that will be planned for a later phase of development
-- Introduce a somewhat "neutral" platform type, which would serve as a signal about an underlying generic cloud-provider presence
+- remove the necessity to make changes in "openshift/api", "openshift/library-go" and dependant infrastructure-related components during basic cloud-provider integration with OpenShift
+- make a cloud provider integration process more accessible and simple to external contributors as well as for RH engineers
+- provide an overview of projected changes to affected components that will be planned for a later phase of development
+- introduce a somewhat "neutral" platform type, which would serve as a signal about an underlying generic cloud-provider presence
### Non-Goals
@@ -114,16 +114,16 @@ without the necessity of tying to Red Hat's internal processes or keeping a fork
## Proposal
-Our main goal is to simplify a new cloud providers integration process with the OpenShift/OKD. To achieve this
-we are proposing to add new "External" [PlatformType](https://github.com/openshift/api/blob/51f399230d604fa013c2bb341040c4ad126e7309/config/v1/types_infrastructure.go#L128)
-along with respective Spec and Status structures into the "openshift/api".
+Our main goal is to simplify the integration process for new cloud providers in OpenShift/OKD. To achieve this
+we are proposing to add a new "External" [PlatformType](https://github.com/openshift/api/blob/51f399230d604fa013c2bb341040c4ad126e7309/config/v1/types_infrastructure.go#L128)
+along with respective Spec and Status structures in openshift/api.
-Such a generic platform type will serve as a signal for built-in Openshift operators about an underlying cloud-provider presence.
+Such a generic platform type will serve as a signal for built-in OpenShift operators about an underlying cloud-provider presence.
Related PlatformSpec and PlatformStatus type structures will serve as a source of generic configuration information for
-the Openshift-specific operators.
+the OpenShift-specific operators.
Having that special platform type will allow infrastructure partners to clearly designate when their OpenShift
-deployments contain components that replaces and/or supplement the core Red Hat components.
+deployments contain components that replace and/or supplement the core Red Hat components.
### Implementation phases
@@ -147,7 +147,7 @@ There are several topics in this area that would be wise to defer for upcoming p
1. Define missing capabilities and their concrete behaviour, for example, add a "capability" for machine-api
2. Precisely define the reaction of the operators listed below for the "External" platform type
-3. Define and document concrete mechanism for supplement cluster with provider-specific components during installation time (CCM, MAPI controller, DNS controller)
+3. Define and document concrete mechanisms for supplementing a cluster with provider-specific components at installation time (CCM, MAPI controller, DNS controller)
4. Research the necessity for engagement and api extension for ["on-prem"-like in-cluster network infrastructure](https://github.com/openshift/enhancements/blob/ce4d303db807622687159eb9d3248285a003fabb/enhancements/network/baremetal-networking.md) for the "External" platform.
This will depend on demand from partner cloud providers and their cloud capabilities (the presence of a load-balancer-like concept, for example).
@@ -160,8 +160,8 @@ and [PlatformStatus](https://github.com/openshift/api/blob/51f399230d604fa013c2b
of the infrastructure resource.
Given that PlatformSpec and PlatformStatus are defined as "discriminated unions" and are required to have the platform type encoded within
-"openshift/api" beforehand, it creates a significant footprint and plenty of effort from Red Hat engineers to create the initial technical enablement of
-a new cloud provider and mostly impossible without Red Hat engineering engagement.
+"openshift/api" beforehand, it requires significant involvement and effort from Red Hat engineers to create the initial technical enablement of
+a new cloud provider and is effectively impossible without Red Hat engineering engagement.
Since a lot of infrastructure related components (such as [CCCMO](https://github.com/openshift/cluster-cloud-controller-manager-operator), [Machine API operator](https://github.com/openshift/machine-api-operator), [Machine Config Operator](https://github.com/openshift/machine-config-operator), [Windows Machine Config Operator](https://github.com/openshift/windows-machine-config-operator) and so on)
require information about, at least, the presence of an underlying cloud provider, the "None" platform does not fit well as a signal in such a situation.
@@ -169,7 +169,7 @@ require information about, at least, the presence of an underlying cloud provide
A special, built-in, and somewhat generic platform type that will signal about the presence of an underlying infrastructure platform without
platform-specific details will help to reduce the number of changes across OCP repositories
and simplify the initial integration work for non-Red Hat contributors.
-Such a new ability will allow smaller / regional cloud providers to build and test their integration with the OpenShift
+Such a new ability will allow smaller / regional cloud providers to build and test their integration with OpenShift
with considerably less effort.
Additionally, there are difficulties that are present today due to having a predefined list of platforms.
@@ -180,9 +180,9 @@ A few examples:
#### Conjunction with Capabilities
-In the future, at some degree, [capabilites selection](https://github.com/openshift/enhancements/blob/master/enhancements/installer/component-selection.md)
-approach might help to solve the issue and give a room for supplementing *some* platform-dependent components, however some integral parts of
-OpenShift can not be disabled and still requires a signal about an underlying platform, for example, KCM and MCO, in respect of the enablement of
+In the future, to some degree, an approach based on [capabilites selection](https://github.com/openshift/enhancements/blob/master/enhancements/installer/component-selection.md)
+might help to solve the issue and provide an option for supplementing *some* platform-dependent components. However, some integral parts of
+OpenShift cannot be disabled and still require a signal about the underlying platform, for example, KCM and MCO, with respect to enabling an
[external cloud controller manager](https://kubernetes.io/docs/concepts/architecture/cloud-controller/).
One of the possible examples of the interaction of the capabilities with the "External" platform type would be the MachineAPI and the Machine Api Operator.
@@ -197,10 +197,10 @@ and replicating work that was already done by Red Hat engineers.
This section enumerates OpenShift's components and briefly elaborates the future plans around this proposal.
During [initial implementation](#implementation-phases) we must ensure that all OpenShift's components treat "External" platform in the same way as
-"None" to ensure we do not disrupt the current openshift operation.
+"None" in order to ensure a consistent baseline across OpenShift components.
In the future, we will need to change the behavior of OpenShift components to be able to receive supplemental provider-specific components from an infrastructure provider
-or, if a component manages something else (i.e. kubelet, kcm), adjust its behaviour (set `--cloud-provider=external` arg to kubelet for example).
+or, if a component manages something else (e.g. kubelet, kcm), adjust its behaviour (set `--cloud-provider=external` arg to kubelet for example).
Specific component changes will be described in detail within separate enhancement documents on a per-component basis.
@@ -208,7 +208,7 @@ Specific component changes will be described in detail within separate enhanceme
Significant part of the code around PlatformType handling lives in the ["openshift/library-go"](https://github.com/openshift/library-go/blob/e1213f6ec5d10aa4aa8a4cac2780b1dc674c0396/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go).
-Currently, this code is responsible for the decision around kubelet and kcm flags. Precisely, [IsCloudProviderExternal](https://github.com/openshift/library-go/blob/e1213f6ec5d10aa4aa8a4cac2780b1dc674c0396/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go#L154) function
+Currently, this code is responsible for the decision around kubelet and kcm flags. Specifically, the [IsCloudProviderExternal](https://github.com/openshift/library-go/blob/e1213f6ec5d10aa4aa8a4cac2780b1dc674c0396/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go#L154) function
is used for decisions around kubelet and KCM flags (within MCO and KCMO respectively).
Also, this code is used for the decision-making about CCM operator engagement.
@@ -241,8 +241,8 @@ This flag is [crucial](https://kubernetes.io/docs/tasks/administer-cluster/runni
Initially, the new "External" platform should be treated similarly to PlatformType "None" by the MCO, and do not set up any cloud-specific flags for the kubelet.
Then, down the road (during [phase 3](#implementation-phases)), it would be expected for the MCO to use the "External" platform type and its spec as a signal about the underlying platform and cloud controller manager presence and operate accordingly.
-For an explicit signal about the necessity to set `--cloud-provider=external` flag to the kubelet, we will use the `CloudControllerManager` field of the `ExternalPlatformSpec`, which is
-described in the [API Extensions](#api-extensions) section down below.
+For an explicit signal about the necessity to set `--cloud-provider=external` flag to the kubelet, we will use the `CloudControllerManager` field of the `ExternalPlatformSpec`,
+which is described in the [API Extensions](#api-extensions) section down below.
#### Windows Machine Config Operator
@@ -265,9 +265,9 @@ to provide users additional knobs to configure this behaviour or, perhaps, check
Responsible for deploying platform-specific Cloud Controller Manager as well as for handling a number of OpenShift's
specific peculiarities (such as populating proxy settings for CCMs, sync credentials, and so on).
-The code from the [library-go](#library-go) using for decision-making about operator engagement.
+The code from the [library-go](#library-go) is used for decision-making about operator engagement.
In case library-go's [IsCloudProviderExternal](https://github.com/openshift/library-go/blob/e1213f6ec5d10aa4aa8a4cac2780b1dc674c0396/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go#L154) function
-indicates that cloud provider is external and the operator encounters a platform which it is not aware of it will go into 'Degraded' state.
+indicates that the cloud provider is external and the operator encounters a platform which it is not aware of, it will go into 'Degraded' state.
During the first phases of the "External" platform type enablement, this operator should be just disabled.
This might be done with changes within the [library-go](#library-go) and further dependency updates or, better,
@@ -336,10 +336,10 @@ since we're providing enough possibilities to customize Image Registry storage b
Within the ingress operator, a PlatformType affects two things:
1. Choosing EndpointPublishingStrategy, which is `HostNetworkStrategyType` for "None" and unknown PlatformType
-2. Creating dns provider on some platforms. This logic does not engage for "None" or unknown PlatformType
+2. Creating DNS provider on some platforms. This logic does not engage for "None" or unknown PlatformType. The DNS provider is used to create a wildcard DNS record for ingress when using `LoadBalancerServiceStrategyType`. It is not used for `HostNetworkStrategyType`.
-Speaking about `LoadBalancer` [EndpointPublishingStrategy](https://docs.openshift.com/container-platform/4.11/networking/ingress-operator.html#nw-ingress-controller-configuration-parameters_configuring-ingress) -
-Cluster Ingress Operator might be reconfigured for using it as a day2 operation.
+With regard to the [EndpointPublishingStrategy](https://docs.openshift.com/container-platform/4.11/networking/ingress-operator.html#nw-ingress-controller-configuration-parameters_configuring-ingress),
+the cluster admin can configure Cluster Ingress Operator to use `LoadBalancerServiceStrategyType` as a day two operation.
The operator itself creates `Service` objects with correct provider-specific annotations,
the actual handling of such objects happens in a provider-specific [cloud controller manager](https://kubernetes.io/docs/concepts/architecture/cloud-controller/).
@@ -366,7 +366,7 @@ and design a way for configuring platform-specific CNI behaviour.
### Workflow Description
-During [phase 1](#implementation-phases) proposed changes intended to have no effect and the "External"
+During [phase 1](#implementation-phases), the proposed changes are intended to have no effect, and the "External"
platform type should be handled the same as the "None", so no specific user interaction is expected.
### API Extensions
@@ -452,14 +452,14 @@ type PlatformStatus struct {
#### Support burden
There is concern that *random* customers will use this feature out of context
and create a support burden. However, using such platform type in conjunction with [capabilites selection](https://github.com/openshift/enhancements/blob/master/enhancements/installer/component-selection.md)
-could give us a clear signal about how to properly triage 3d party created replacements for Red Hat components.
+could give us a clear signal about how to properly triage third-party created replacements for Red Hat components.
### Drawbacks
Current approach with having statically defined platform list is already there, quite transparent and battle-hardened.
Changing it by adding the new, way less specific platform type would mean a significant step away from current design patterns in this area.
-Also, future support strategy is not completely clear due to we have plans around enablement of 3d party platform-specific components, which
+Also, future support strategy is not completely clear due to our plans around enablement of third-party platform-specific components, which
codebase would be mostly out of our control.
## Design Details
@@ -473,7 +473,7 @@ codebase would be mostly out of our control.
**Q**: Should we gate the "External" platform addition behind the feature gate by generating separate CRD for TPNU clusters?
**A**: There seems to be a soft consensus that we do not need to gate these changes behind Tech Preview if it is not necessary.
-Due to operators intended to react on the "External" platform the same as for the "None" one during the first phases,
+Because operators are intended to react on the "External" platform the same as for the "None" one during the first phases,
gating these API extensions does not seem needed.
Related discussion: [1](https://github.com/openshift/enhancements/pull/1234#discussion_r968935259)
@@ -489,12 +489,12 @@ Related discussions: [1](https://github.com/openshift/enhancements/pull/1234#dis
---
**Q**: Do we need an API for the MAPI components similar to the proposed [CCM one](#api-extensions)
-to allow users to choose how the MAPI components are deployed.
+to allow users to choose how the MAPI components are deployed?
**A**: We do not see an absolute necessity to add such API knobs right now. For the moment combination of the
"External" platform and an enabled MAPI capability look like a sufficient signal.
By the nature of the [capabilities mechanism](https://github.com/openshift/enhancements/blob/master/enhancements/installer/component-selection.md#summary)(i.e., no MAO deployment, no MAPI CRDs),
-if Machine API operator running and detects the "External" platform, that is the signal to it that *someone* is going to run a machine controller.
+if Machine API operator is running and detects the "External" platform, that is the signal to it that *someone* is going to run a machine controller.
Given that capabilities "API" is already added and in use, introducing additional knobs which will interfere with that
would mean more code changes and the necessity of establishing a mechanism for communicating with users (i.e., what should handle such API if MAPI is disabled by the capabilities mechanism).
@@ -509,8 +509,8 @@ Related discussions: [1](https://github.com/openshift/enhancements/pull/1234#iss
During the first stages, we must ensure that OpenShift [built-in operators whose behaviour depends on platform type](#affected-components) treat the "External" platform type the same way as "None".
To achieve this - existing infrastructure and mechanisms employed for exercising topologies with the "None" platform type might be used.
-For the moment of writing, the only workflow where the "None" platform tests is [upi-conf-vsphere-platform-none-ovn](https://steps.ci.openshift.org/workflow/upi-vsphere-platform-none-ovn).
-Based on this workflow, a new one with platform type "External" with a respective set of jobs should be added to ensure that we do not disrupt the current openshift operation.
+At the time of writing, the only workflow where the "None" platform tests is [upi-conf-vsphere-platform-none-ovn](https://steps.ci.openshift.org/workflow/upi-vsphere-platform-none-ovn).
+Based on this workflow, a new one with platform type "External" with a respective set of jobs should be added to ensure that we do not disrupt the current OpenShift operation.
However, given that vSphere is the only platform where we're exercising clusters installation with platform "None" specified,
it would be beneficial to develop additional workflows using a provider with better capacity and performance (AWS or GCP, perhaps).
@@ -544,13 +544,13 @@ should not affect upgrade/downgrade process across existing clusters.
### Version Skew Strategy
-Since setting PlatformType is a day 0 operation, sets up during cluster installation and does not expect to be changed during cluster lifecycle,
+Since PlatformType is set as a day zero operation during cluster installation and is not expected to be changed during the cluster lifecycle,
version skew should not be the case there.
### Operational Aspects of API Extensions
It should be no different from other PlatformTypes. Scalability, API throughput and availability should not be affected.
-In the first phases, it is expected to work the same way as for PlatformType "None"
+In the first phases, it is expected to work the same way as for PlatformType "None".
#### Failure Modes
@@ -559,7 +559,7 @@ In the first phases, it is expected to work the same way as for PlatformType "No
#### Support Procedures
-During the first phases of this effort, support procedures should be no different as for cluster with PlatformType equals "None"
+During the first phases of this effort, support procedures should be no different from clusters with PlatformType set to "None".
## Implementation History
@@ -567,6 +567,8 @@ TBD
## Alternatives
+### Status Quo
+
Leave things as is, i.e., encode every new cloud platform statically into "openshift/api" from the beginning of a technical enablement process.
### Proceed to use "None" Platform type
@@ -583,4 +585,4 @@ We could proceed to leverage PlatformType "None"; however, there are some diffic
## Infrastructure Needed
-- Additional CI workflows and set of CI jobs that exercise Openshift installation with the new "External" platform.
\ No newline at end of file
+- Additional CI workflows and set of CI jobs that exercise OpenShift installation with the new "External" platform.
\ No newline at end of file

original_message:
Update and cleanup wording

Update wording based on @Miciah comments,
some phrases should look better now.


message:
Update and cleanup wording
Update wording based on a feedback

diff:
@@ -199,7 +199,7 @@ This section enumerates OpenShift's components and briefly elaborates the future
During [initial implementation](#implementation-phases) we must ensure that all OpenShift's components treat "External" platform in the same way as
"None" in order to ensure a consistent baseline across OpenShift components.
-In the future, we will need to change the behavior of OpenShift components to be able to receive supplemental provider-specific components from an infrastructure provider
+In the future, we will need to change the behavior of OpenShift components on a case-by-case basis to be able to function harmoniously with supplemental provider-specific components from an infrastructure provider
or, if a component manages something else (e.g. kubelet, kcm), adjust its behaviour (set `--cloud-provider=external` arg to kubelet for example).
Specific component changes will be described in detail within separate enhancement documents on a per-component basis.
@@ -483,7 +483,7 @@ Related discussion: [1](https://github.com/openshift/enhancements/pull/1234#disc
on the AWS or GCP, or existing vSphere-based workflows would be enough?
**A**: Adding a job on one additional cloud platform to ensure that the "External" platform type works as intended looks reasonable now,
-but we should mainly rely on in-repo functional tests on a per-component basis and avoid engaging of e2e workflows as much as possible.
+but we should mainly rely on in-repo functional tests on a per-component basis and avoid creating new e2e workflows as much as possible.
Related discussions: [1](https://github.com/openshift/enhancements/pull/1234#discussion_r968934725), [2](https://github.com/openshift/enhancements/pull/1234#discussion_r968936500).


message: Document missed cluster-machine-approver occupied ports

diff:
@@ -9,7 +9,7 @@ reviewers:
approvers:
- "@russelb"
creation-date: 2020-08-26
-last-updated: 2022-08-31
+last-updated: 2022-10-26
status: informational
---
@@ -63,7 +63,7 @@ Ports are assumed to be used on all nodes in all clusters unless otherwise speci
### TCP
| Port | Process | Owning Team | Since | Notes |
-|-------|-----------|-------------|-------|-------|
+|-------|-----------|-------------|------|-------|
| 80 | haproxy | net edge | 3.0 | HTTP routes; baremetal only; only on nodes running router pod replicas |
| 443 | haproxy | net edge | 3.0 | HTTPS routes; baremetal only; only on nodes running router pod replicas |
| 1936 | openshift-router | net edge | 3.0 | healthz/stats; baremetal only; only on nodes running router pod replicas |
@@ -91,6 +91,10 @@ Ports are assumed to be used on all nodes in all clusters unless otherwise speci
| 9120 | metallb | sdn | 4.9 | metrics|
| 9121 | metallb | sdn | 4.9 | metrics|
| 9122 | metallb | sdn | 4.9 | leader election protocol |
+| 9191 | cluster-machine-approver | cluster infra | 4.3 | metrics |
+| 9192 | cluster-machine-approver | cluster infra | 4.3 | metrics |
+| 9193 | cluster-machine-approver-capi | cluster infra | 4.11 | metrics |
+| 9194 | cluster-machine-approver-capi | cluster infra | 4.11 | metrics |
| 9200-9219 | various CSI drivers | storage | 4.8 | metrics |
| 9258 | cluster-cloud-controller-manager-operator | cluster infra | 4.9 | metrics, control plane only |
| 9444 | haproxy | sdn | 4.7 | on-prem internal loadbalancer, healthcheck port |


message: Add feature test for prepare arguments fix

diff:
@@ -305,3 +305,44 @@ Feature: Per-suite helper containers
"""
When I run "behat --no-colors -f progress features/container.feature"
Then it should pass
+
+ Scenario: Mix of typehinted arguments and numbered arguments (fix #991)
+ Given a file named "behat.yml" with:
+ """
+ default:
+ suites:
+ default:
+ contexts:
+ - FirstContext:
+ - foo
+ - "@typehinted_service"
+ - bar
+
+ services:
+ typehinted_service:
+ class: stdClass
+ """
+ And a file named "features/container_args.feature" with:
+ """
+ Feature:
+ Scenario:
+ Given foo
+ """
+ And a file named "features/bootstrap/FirstContext.php" with:
+ """
+ <?php use Behat\Behat\Context\Context;
+
+ class FirstContext implements Context {
+ public function __construct($foo, stdClass $service, $bar) {
+ // the first argument is a placeholder while #990 is still opened
+ // otherwise, if we had only the SharedService and $arg2, it would not
+ // show the fix that was made in #993
+ }
+
+ /** @Given foo */
+ public function foo() {
+ }
+ }
+ """
+ When I run "behat --no-colors -f progress features/container_args.feature"
+ Then it should pass

license: MIT License

repo: behat/behat


message: Do not treat first argument as numbered argument if typehinted

diff:
@@ -88,7 +88,7 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
foreach ($arguments as $key => $val) {
if ($this->isStringKeyAndExistsInParameters($key, $parameterNames)) {
$namedArguments[$key] = $val;
- } elseif ($num = $this->getParameterNumberWithTypehintingValue($parameters, $val)) {
+ } elseif (null !== ($num = $this->getParameterNumberWithTypehintingValue($parameters, $val))) {
$typehintedArguments[$num] = $val;
} else {
$numberedArguments[] = $val;


message: Alter scenario for

diff:
@@ -314,7 +314,6 @@ Feature: Per-suite helper containers
default:
contexts:
- FirstContext:
- - foo
- "@typehinted_service"
- bar
@@ -333,10 +332,7 @@ Feature: Per-suite helper containers
<?php use Behat\Behat\Context\Context;
class FirstContext implements Context {
- public function __construct($foo, stdClass $service, $bar) {
- // the first argument is a placeholder while #990 is still opened
- // otherwise, if we had only the SharedService and $arg2, it would not
- // show the fix that was made in #993
+ public function __construct(stdClass $service, $bar) {
}
/** @Given foo */

original_message: Alter scenario for #993


message: Remove short array syntax

diff:
@@ -285,7 +285,7 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
callable $predicate
) {
foreach ($candidates as $candidateIndex => $candidate) {
- if (call_user_func_array($predicate, [$parameter->getClass(), $candidate])) {
+ if (call_user_func_array($predicate, array($parameter->getClass(), $candidate))) {
$num = $parameter->getPosition();
$arguments[$num] = $candidate;

original_message: Remove short array syntax


message: Rework appveyor

diff:
@@ -6,7 +6,7 @@ clone_folder: c:\projects\behat
environment:
matrix:
- - PHP_DOWNLOAD_FILE: php-7.1.3-Win32-VC14-x86.zip
+ - php: 7.2
branches:
only:
@@ -16,31 +16,48 @@ skip_commits:
message: /\[ci skip\]/
cache:
- - c:\php -> appveyor.yml
+ - C:\ProgramData\chocolatey\bin -> appveyor.yml
+ - C:\ProgramData\chocolatey\lib -> appveyor.yml
+ - C:\tools\php -> appveyor.yml
+ - C:\tools\composer -> appveyor.yml
+ - '%LOCALAPPDATA%\Composer\files'
init:
- - SET PATH=c:\php;%PATH%
+ - SET PATH=C:\Program Files\OpenSSL;c:\tools\php;C:\tools\composer;%PATH%
- SET COMPOSER_NO_INTERACTION=1
- - SET PHP=1
- SET ANSICON=121x90 (121x90)
- git config --global core.autocrlf input
install:
- - IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php)
- - cd c:\php
- - IF %PHP%==1 appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/%PHP_DOWNLOAD_FILE%
- - IF %PHP%==1 7z x %PHP_DOWNLOAD_FILE% -y > 7z.log
- - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat
- - appveyor DownloadFile https://getcomposer.org/composer.phar
- - copy php.ini-production php.ini /Y
- - echo date.timezone="UTC" >> php.ini
- - echo extension_dir=ext >> php.ini
- - echo extension=php_openssl.dll >> php.ini
- - echo extension=php_curl.dll >> php.ini
- - echo extension=php_mbstring.dll >> php.ini
- - echo extension=php_fileinfo.dll >> php.ini
+ - ps: |
+ if (!(Test-Path c:\tools\php)) {
+ appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','')
+ Get-ChildItem -Path c:\tools\php
+ cd c:\tools\php
+
+ # Set PHP environment items that are always needed
+ copy php.ini-production php.ini
+ Add-Content php.ini "`n date.timezone=UTC"
+ Add-Content php.ini "`n extension_dir=ext"
+ Add-Content php.ini "`n extension=php_openssl.dll"
+ Add-Content php.ini "`n extension=php_curl.dll"
+ Add-Content php.ini "`n extension=php_mbstring.dll"
+ Add-Content php.ini "`n extension=php_fileinfo.dll"
+
+ # download Composer
+ if (!(Test-Path C:\tools\composer)) {
+ New-Item -path c:\tools -name composer -itemtype directory
+ }
+
+ if (!(Test-Path c:\tools\composer\composer.phar)) {
+ appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar -Filename C:\tools\composer\composer.phar
+ Set-Content -path 'C:\tools\composer\composer.bat' -Value ('@php C:\tools\composer\composer.phar %*')
+ }
+ }
+
- cd c:\projects\behat
- - composer install --no-progress --ansi
+ - appveyor-retry composer self-update
+ - appveyor-retry composer install --no-progress --ansi
test_script:
- cd c:\projects\behat

original_message: Rework appveyor


message: Test travis against php 7.2

diff:
language: php
-php: [5.6, 7.0, 7.1]
+php: [5.6, 7.0, 7.1, 7.2]
sudo: false
@@ -20,8 +20,8 @@ matrix:
env: SYMFONY_VERSION='2.7.*'
- php: 5.6
env: SYMFONY_VERSION='2.8.*'
- - php: 7.1
- env: SYMFONY_VERSION='4.0.*@dev'
+ - php: 7.2
+ env: SYMFONY_VERSION='^3.4'
before_install:
- phpenv config-rm xdebug.ini

original_message: Test travis against php 7.2


message: Do not call mb_strpos on non-string arguments

diff:
@@ -63,7 +63,7 @@ final class ServicesResolver implements ArgumentResolver
*/
private function resolveArgument($value)
{
- if (0 === mb_strpos($value, '@')) {
+ if (is_string($value) && 0 === mb_strpos($value, '@')) {
return $this->container->get(mb_substr($value, 1));
}


message: Add scenario for array arguments

diff:
@@ -466,3 +466,42 @@ Feature: Context consistency
2 scenarios (2 passed)
2 steps (2 passed)
"""
+
+ Scenario: Array arguments
+ Given a file named "behat.yml" with:
+ """
+ default:
+ suites:
+ default:
+ contexts:
+ - FirstContext:
+ - [foo, bar]
+ """
+ And a file named "features/context-args-array.feature" with:
+ """
+ Feature:
+ Scenario:
+ Given foo
+ """
+ And a file named "features/bootstrap/FirstContext.php" with:
+ """
+ <?php use Behat\Behat\Context\Context;
+
+ class FirstContext implements Context {
+ private $foo;
+
+ public function __construct(array $foo) {
+ $this->foo = $foo;
+ }
+
+ /** @Given foo */
+ public function foo() {
+ PHPUnit\Framework\Assert::assertInternalType('array', $this->foo);
+
+ PHPUnit\Framework\Assert::assertSame('foo', $this->foo[0]);
+ PHPUnit\Framework\Assert::assertSame('bar', $this->foo[1]);
+ }
+ }
+ """
+ When I run "behat --no-colors -f progress features/context-args-array.feature"
+ Then it should pass

original_message: Add scenario for array arguments


message: Make the condition more readable in ArgumentAutowirer

diff:
@@ -14,6 +14,7 @@ use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use ReflectionFunctionAbstract;
use ReflectionParameter;
+use ReflectionException;
/**
* Automatically wires arguments of a given function from inside the container by using type-hitns.
@@ -72,6 +73,18 @@ final class ArgumentAutowirer
*/
private function isArgumentWireable(array $arguments, $index, ReflectionParameter $parameter)
{
- return !isset($arguments[$index]) && !isset($arguments[$parameter->getName()]) && !array_key_exists($index, $arguments) && !array_key_exists($parameter->getName(), $arguments) && $parameter->getClass();
+ if (isset($arguments[$index]) || array_key_exists($index, $arguments)) {
+ return false;
+ }
+
+ if (isset($arguments[$parameter->getName()]) || array_key_exists($parameter->getName(), $arguments)) {
+ return false;
+ }
+
+ try {
+ return (bool) $parameter->getClass();
+ } catch (ReflectionException $e) {
+ return false;
+ }
}
}


message: Add scenario for null arguments and autowire

diff:
@@ -106,6 +106,41 @@ Feature: Helper services autowire
When I run "behat --no-colors -f progress features/autowire.feature"
Then it should pass
+ Scenario: Null arguments should be skipped
+ Given a file named "behat.yaml" with:
+ """
+ default:
+ suites:
+ default:
+ contexts:
+ - FeatureContext:
+ name: null
+ services: ServiceContainer
+ autowire: true
+ """
+ And a file named "features/autowire.feature" with:
+ """
+ Feature:
+ Scenario:
+ Given a step
+ """
+ And a file named "features/bootstrap/FeatureContext.php" with:
+ """
+ <?php use Behat\Behat\Context\Context;
+
+ class FeatureContext implements Context {
+ public function __construct($name, Service1 $s1, Service3 $s3)
+ {
+ PHPUnit\Framework\Assert::assertNull($name);
+ }
+
+ /** @Given a step */
+ public function aStep() {}
+ }
+ """
+ When I run "behat --no-colors -f progress features/autowire.feature"
+ Then it should pass
+
Scenario: Unregistered services as constructor arguments
Given a file named "features/autowire.feature" with:
"""


message: If ->getClass() is not available, ignore it

diff:
@@ -13,6 +13,7 @@ namespace Behat\Testwork\Argument;
use ReflectionFunctionAbstract;
use ReflectionClass;
use ReflectionParameter;
+use ReflectionException;
/**
* Organises function arguments using its reflection.
@@ -225,7 +226,11 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
continue;
}
+ try {
$reflectionClass = $parameter->getClass();
+ } catch (ReflectionException $e) {
+ continue;
+ }
if (!$reflectionClass) {
continue;


message: 3.5.0 release prep

diff:
"extra": {
"branch-alias": {
- "dev-master": "3.4.x-dev"
+ "dev-master": "3.5.x-dev"
}
},

diff:
@@ -46,7 +46,7 @@ use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
*/
final class ApplicationFactory extends BaseFactory
{
- const VERSION = '3.4-dev';
+ const VERSION = '3.5.0';
/**
* {@inheritdoc}

original_message: 3.5.0 release prep


message: Update version number for 3.6.0

diff:
@@ -46,7 +46,7 @@ use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
*/
final class ApplicationFactory extends BaseFactory
{
- const VERSION = '3.5.0';
+ const VERSION = '3.6.0';
/**
* {@inheritdoc}

original_message: Update version number for 3.6.0


message: Update for 3.6.1 release

diff:
@@ -4,13 +4,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [3.6.1] - 2019-02-06
+### Fixed
+ * [#1278](https://github.com/Behat/Behat/pull/1278): Fix fatal when unexpected symfony/event-dispatcher version is installed
+
## [3.6.0] - 2019-02-04
- * [#1256](https://github.com/Behat/Behat/pull/1256): Update dependencies to support Symfony 5.x
### Added
* [#1244](https://github.com/Behat/Behat/pull/1244): Hide internal steps from stack traces in very verbose mode
### Fixed
* [#1238](https://github.com/Behat/Behat/pull/1238): Don't run Junit output if ext-dom is not present (and suggest in composer)
### Changed
+ * [#1256](https://github.com/Behat/Behat/pull/1256): Update dependencies to support Symfony 5.x
* [#1171](https://github.com/Behat/Behat/pull/1171): Remove symfony/class-loader dependency
* [#1170](https://github.com/Behat/Behat/pull/1170): Switch to PSR-4 autoloading
* [#1230](https://github.com/Behat/Behat/pull/1230): PHP 7.3 support

diff:
@@ -46,7 +46,7 @@ use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
*/
final class ApplicationFactory extends BaseFactory
{
- const VERSION = '3.6.0';
+ const VERSION = '3.6.1';
/**
* {@inheritdoc}

original_message: Update for 3.6.1 release


message: Start testing on PHP8 in travis

diff:
@@ -18,6 +18,8 @@ jobs:
env: DEPENDENCIES='low'
- php: 7.4
env: SYMFONY_VERSION='^4.4'
+ - php: nightly
+ env: PHP8=true
before_install:
- phpenv config-rm xdebug.ini || echo "XDebug is not enabled"
@@ -25,14 +27,15 @@ before_install:
before_script:
- if [ "$SYMFONY_VERSION" != "" ]; then composer require --no-update "symfony/symfony:${SYMFONY_VERSION}"; fi;
- if [ "$SKIP_INTEROP" != "" ]; then composer remove --dev --no-update container-interop/container-interop; fi;
- - if [ "$DEPENDENCIES" != "low" ]; then composer update; fi;
+ - if [ "$DEPENDENCIES" != "low" ]; then composer update $([ -z "$PHP8" ] || echo "--ignore-platform-reqs") ; fi;
- if [ "$DEPENDENCIES" = "low" ]; then composer update --prefer-lowest; fi;
- echo 'zend.exception_ignore_args=Off' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- export PATH=./bin:$PATH
script:
- ./vendor/bin/phpunit
- - behat -fprogress --strict $([ -z "$SKIP_INTEROP" ] || echo "--tags ~@interop")
+ - behat -fprogress --strict $([ -z "$SKIP_INTEROP" ] || echo "--tags ~@interop&&~@php8")
+ - if [ "$PHP8" = true ]; then behat -fprogress --strict --tags=@php8; fi;
before_deploy:
- curl -LSs https://box-project.github.io/box2/installer.php | php

change_type: ADD

diff:
+default:
+ gherkin:
+ filters:
+ tags: ~@php8

original_message: Start testing on PHP8 in travis


message: Allow newer PHPUnit

diff:
"require-dev": {
"symfony/process": "^4.4 || ^5.0",
- "phpunit/phpunit": "^8.5",
+ "phpunit/phpunit": "^8.5 || ^9.0",
"herrera-io/box": "~1.6.1",
"container-interop/container-interop": "^1.2"
},

original_message: Allow newer PHPUnit


message: Remove deprecated reflection from MixedArgumentOrganiser

diff:
@@ -131,17 +131,14 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
/**
* Checks if value matches typehint of provided parameter.
- *
- * @param object $value
- * @param ReflectionParameter $parameter
- *
- * @return bool
*/
- private function isValueMatchesTypehintedParameter($value, ReflectionParameter $parameter)
+ private function isValueMatchesTypehintedParameter($value, ReflectionParameter $parameter) : bool
{
- $typehintRefl = $parameter->getClass();
+ if ($typehintRefl = $this->getReflectionClassFromParameter($parameter)) {
+ return $typehintRefl->isInstance($value);
+ }
- return $typehintRefl && $typehintRefl->isInstance($value);
+ return false;
}
/**
@@ -217,29 +214,36 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
* @param ReflectionParameter[] $parameters Constructor Arguments
* @return ReflectionParameter[] Filtered $parameters
*/
- private function filterApplicableTypehintedParameters(array $parameters)
+ private function filterApplicableTypehintedParameters(array $parameters) : array
{
- $filtered = array();
+ return array_filter($parameters,
+ function($parameter, $num) {
+ return !$this->isArgumentDefined($num)
+ && $this->getReflectionClassFromParameter($parameter);
+ },
+ ARRAY_FILTER_USE_BOTH
+ );
- foreach ($parameters as $num => $parameter) {
- if ($this->isArgumentDefined($num)) {
- continue;
}
+ private function getReflectionClassFromParameter(\ReflectionParameter $parameter) : ?ReflectionClass
+ {
try {
- $reflectionClass = $parameter->getClass();
- } catch (ReflectionException $e) {
- continue;
+ if (!$parameter->hasType()) {
+ return null;
}
+ $type = $parameter->getType()->getName();
- if (!$reflectionClass) {
- continue;
+ if ($type == 'self') {
+ $type = $parameter->getDeclaringClass();
+ } elseif ($type == 'parent') {
+ $type = $parameter->getDeclaringClass()->getParentClass();
}
- $filtered[$num] = $parameter;
+ return new ReflectionClass($type); // will throw
+ } catch (ReflectionException $e) {
+ return null;
}
-
- return $filtered;
}
/**
@@ -283,7 +287,7 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
$predicate
) {
foreach ($candidates as $candidateIndex => $candidate) {
- if ($predicate($parameter->getClass(), $candidate)) {
+ if (($class = $this->getReflectionClassFromParameter($parameter)) && $predicate($class, $candidate)) {
$num = $parameter->getPosition();
$arguments[$num] = $candidate;

diff:
+<?php
+declare(strict_types=1);
+
+namespace Behat\Tests\Testwork\Argument;
+
+use Behat\Testwork\Argument\MixedArgumentOrganiser;
+use PHPUnit\Framework\TestCase;
+
+final class MixedArgumentOrganiserTest extends TestCase
+{
+ private $organiser;
+
+ function setUp() : void
+ {
+ $this->organiser = new MixedArgumentOrganiser();
+ }
+
+ /** @test */
+ function it_organises_nothing_if_no_args()
+ {
+ $r = new \ReflectionFunction(
+ function(\DateTimeInterface $d) {}
+ );
+ $args = [];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_position()
+ {
+ $r = new \ReflectionFunction(
+ function($x, $y) {}
+ );
+ $args = [
+ 1,
+ 2,
+ 3
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([1,2], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_name()
+ {
+ $r = new \ReflectionFunction(
+ function($date) {}
+ );
+ $args = [
+ 'date' => $date = new \DateTime(),
+ 'x' => new \stdClass()
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame(['date' => $date], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_type()
+ {
+ $r = new \ReflectionFunction(
+ function(\DateTimeInterface $d) {}
+ );
+ $args = [
+ 'x' => $date = new \DateTime(),
+ 'y' => new \stdClass()
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([$date], $organised);
+ }
+
+ /** @test */
+ function it_matches_args_by_name_over_type()
+ {
+ $r = new \ReflectionFunction(
+ function(\DateTimeInterface $a, $date) {}
+ );
+ $args = [
+ 'date' => $date = new \DateTime(),
+ 'x' => 1
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([1, 'date' => $date], $organised);
+ }
+}


message: Let MixedArgumentOrganiser deal with union types

diff:
@@ -134,8 +134,10 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
*/
private function isValueMatchesTypehintedParameter($value, ReflectionParameter $parameter) : bool
{
- if ($typehintRefl = $this->getReflectionClassFromParameter($parameter)) {
- return $typehintRefl->isInstance($value);
+ foreach($this->getReflectionClassesFromParameter($parameter) as $typehintRefl) {
+ if($typehintRefl->isInstance($value)) {
+ return true;
+ }
}
return false;
@@ -219,31 +221,54 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
return array_filter($parameters,
function($parameter, $num) {
return !$this->isArgumentDefined($num)
- && $this->getReflectionClassFromParameter($parameter);
+ && $this->getReflectionClassesFromParameter($parameter);
},
ARRAY_FILTER_USE_BOTH
);
}
- private function getReflectionClassFromParameter(\ReflectionParameter $parameter) : ?ReflectionClass
+ /**
+ * @return ReflectionClass[]
+ */
+ private function getReflectionClassesFromParameter(\ReflectionParameter $parameter): array
{
- try {
+ $classes = [];
+
if (!$parameter->hasType()) {
- return null;
+ return $classes;
+ }
+
+ $type = $parameter->getType();
+
+ if ($type instanceof \ReflectionNamedType) {
+ $types = [$type];
}
- $type = $parameter->getType()->getName();
+ elseif ($parameter->getType() instanceof \ReflectionUnionType) {
+ $types = $type->getTypes();
+ }
+ else {
+ $types = [];
+ }
+
+ foreach ($types as $type) {
- if ($type == 'self') {
- $type = $parameter->getDeclaringClass();
- } elseif ($type == 'parent') {
- $type = $parameter->getDeclaringClass()->getParentClass();
+ $typeString = $type->getName();
+
+ if ($typeString == 'self') {
+ $typeString = $parameter->getDeclaringClass();
+ } elseif ($typeString == 'parent') {
+ $typeString = $parameter->getDeclaringClass()->getParentClass();
}
- return new ReflectionClass($type); // will throw
+ try {
+ $classes[] = new ReflectionClass($typeString);
} catch (ReflectionException $e) {
- return null;
+ continue;
+ }
}
+
+ return $classes;
}
/**
@@ -287,7 +312,8 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
$predicate
) {
foreach ($candidates as $candidateIndex => $candidate) {
- if (($class = $this->getReflectionClassFromParameter($parameter)) && $predicate($class, $candidate)) {
+ foreach($this->getReflectionClassesFromParameter($parameter) as $class) {
+ if ($predicate($class, $candidate)) {
$num = $parameter->getPosition();
$arguments[$num] = $candidate;
@@ -299,6 +325,7 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
return true;
}
}
+ }
return false;
}

diff:
@@ -92,4 +92,27 @@ final class MixedArgumentOrganiserTest extends TestCase
$this->assertSame([1, 'date' => $date], $organised);
}
+
+ /** @test */
+ function it_matches_union_types()
+ {
+ if (\PHP_VERSION_ID < 80000) {
+ $this->markTestSkipped('Union types are not supported');
+ }
+
+ $r = eval(<<<CODE
+ return new \ReflectionFunction(
+ function(int|\DateTimeInterface \$a) {}
+ );
+CODE
+ );
+ $args = [
+ 'date' => $date = new \DateTime(),
+ 'x' => 1
+ ];
+
+ $organised = $this->organiser->organiseArguments($r, $args);
+
+ $this->assertSame([$date], $organised);
+ }
}


message: Remove deprecated reflection calls from ReturnTypeTransformation

diff:
@@ -637,3 +637,40 @@ Feature: Step Arguments Transformations
4 scenarios (4 passed)
8 steps (8 passed)
"""
+
+ @php8
+ Scenario: By-type transformations don't trigger from union types
+ Given a file named "features/union-transforms.feature" with:
+ """
+ Feature:
+ Scenario:
+ Given I am "everzet"
+ And she is "lunivore"
+ """
+ And a file named "features/bootstrap/FeatureContext.php" with:
+ """
+ <?php
+ class User {
+ }
+ class FeatureContext implements Behat\Behat\Context\Context
+ {
+ /** @Transform */
+ public function userFromName($name) : User|int
+ {
+ return new User();
+ }
+
+ /**
+ * @Given I am :user
+ * @Given she is :user
+ */
+ public function iAm(User $user) {
+ $this->I = $user;
+ }
+ }
+ """
+ When I run "behat -f progress --no-colors"
+ Then it should fail with:
+ """
+ string given
+ """

diff:
@@ -16,6 +16,7 @@ use Behat\Behat\Transformation\SimpleArgumentTransformation;
use Behat\Testwork\Call\CallCenter;
use Behat\Testwork\Call\RuntimeCallee;
use Closure;
+use ReflectionClass;
use ReflectionFunctionAbstract;
use ReflectionMethod;
use ReflectionParameter;
@@ -127,7 +128,8 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
{
$type = $reflection->getReturnType();
- if (null === $type || $type->isBuiltin()) {
+ // Skip ReflectionUnionType as they can't be relied on for a transform
+ if (null === $type || !($type instanceof \ReflectionNamedType) || $type->isBuiltin()) {
return null;
}
@@ -152,9 +154,12 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
array_filter($this->getCallParameters($definitionCall),
$this->hasIndex($argumentIndex)
),
- $this->isClass()
+ $this->getClassReflection()
);
- return count($parameters) ? current($parameters)->getClass()->getName() : null;
+
+ if (count($parameters)) {
+ return ($this->getClassReflection())(current($parameters))->getName();
+ }
}
/**
@@ -214,10 +219,17 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
*
* @return Closure
*/
- private function isClass()
+ private function getClassReflection()
{
return function (ReflectionParameter $parameter) {
- return $parameter->getClass();
+ $t = $parameter->getType();
+
+ if ($t instanceof ReflectionNamedType) {
+ try {
+ return new ReflectionClass($t->getName());
+ }
+ catch (\TypeError $t) {}
+ }
};
}
}


message: Make JUnit test looser for new format error

diff:
When I run "behat --no-colors -f junit -o junit"
Then it should fail with:
"""
- PHP Fatal error: class@anonymous cannot implement Foo - it is not an interface
+ cannot implement Foo - it is not an interface
"""
And "junit/default.xml" file xml should be like:
"""


message:
Fix error reporting tests that broke due to an E_NOTICE becoming an E_WARNING
I decided to patch over this rather than re-write the tests as they can easily become E_WARNING once we drop PHP 7

diff:
@@ -438,6 +438,9 @@ EOL;
// Replace wrong warning message of HHVM
$output = str_replace('Notice: Undefined index: ', 'Notice: Undefined offset: ', $output);
+ // replace error message that changed in PHP
+ $output = str_replace('Warning: Undefined array key','Notice: Undefined offset:', $output);
+
return trim(preg_replace("/ +$/m", '', $output));
}

diff:
@@ -111,12 +111,12 @@ Feature: Error Reporting
7 steps (5 passed, 1 failed, 1 skipped)
"""
- Scenario: With error reporting ignoring E_NOTICE
+ Scenario: With error reporting ignoring E_NOTICE and E_WARNING
Given a file named "behat.yml" with:
"""
default:
calls:
- error_reporting: 32759
+ error_reporting: 32757
"""
When I run "behat -f progress --no-colors features/e_notice_in_scenario.feature"
Then it should pass


message: Remove deprecated reflection calls from ArgumentAutowirer and related named arguments fix

diff:
@@ -12,6 +12,7 @@ Feature: Helper services autowire
- It only wires arguments that weren't otherwise set
- Services must be last arguments in step definitions
- Services must be last arguments in transformations
+ - Autowiring is not yet triggered for union types
Background:
Given a file named "behat.yaml" with:
@@ -245,3 +246,28 @@ Feature: Helper services autowire
"""
When I run "behat --no-colors -f progress features/autowire.feature"
Then it should pass
+
+ @php8
+ Scenario: Union constructor arguments
+ Given a file named "features/autowire.feature" with:
+ """
+ Feature:
+ Scenario:
+ Given a step
+ """
+ And a file named "features/bootstrap/FeatureContext.php" with:
+ """
+ <?php use Behat\Behat\Context\Context;
+
+ class FeatureContext implements Context {
+ public function __construct(Service1|Service2 $s) {}
+
+ /** @Given a step */
+ public function aStep() {}
+ }
+ """
+ When I run "behat --no-colors -f progress features/autowire.feature"
+ Then it should fail with:
+ """
+ Can not find a matching value for an argument `$s` of the method `FeatureContext::__construct()`
+ """

diff:
@@ -130,7 +130,7 @@ final class ContextFactory
private function createInstance(ReflectionClass $reflection, array $arguments)
{
if (count($arguments)) {
- return $reflection->newInstanceArgs($arguments);
+ return $reflection->newInstanceArgs(array_values($arguments));
}
return $reflection->newInstance();

diff:
@@ -12,12 +12,14 @@ namespace Behat\Behat\HelperContainer;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface as PsrContainerInterface;
+use ReflectionClass;
use ReflectionFunctionAbstract;
+use ReflectionNamedType;
use ReflectionParameter;
use ReflectionException;
/**
- * Automatically wires arguments of a given function from inside the container by using type-hitns.
+ * Automatically wires arguments of a given function from inside the container by using type-hints.
*
* @author Konstantin Kudryashov <ever.zet@gmail.com>
*/
@@ -53,7 +55,7 @@ final class ArgumentAutowirer
$newArguments = $arguments;
foreach ($reflection->getParameters() as $index => $parameter) {
if ($this->isArgumentWireable($newArguments, $index, $parameter)) {
- $newArguments[$index] = $this->container->get($parameter->getClass()->getName());
+ $newArguments[$index] = $this->container->get($this->getClassFromParameter($parameter));
}
}
@@ -81,10 +83,32 @@ final class ArgumentAutowirer
return false;
}
+ if (!$parameter->getType() instanceof ReflectionNamedType) {
+ return false;
+ }
+
+ return (bool) $this->getClassFromParameter($parameter);
+ }
+
+ private function getClassFromParameter(ReflectionParameter $parameter) : ?string
+ {
try {
- return (bool) $parameter->getClass();
+ $typeString = $parameter->getType()->getName();
+
+ if ($typeString == 'self') {
+ return $parameter->getDeclaringClass()->getName();
+ }
+ elseif ($typeString == 'parent') {
+ return $parameter->getDeclaringClass()->getParentClass()->getName();
+ }
+
+ // will throw if not valid class
+ new ReflectionClass($typeString);
+
+ return $typeString;
+
} catch (ReflectionException $e) {
- return false;
+ return null;
}
}
}


message: Use COMPOSER_FLAGS in travis config

diff:
@@ -15,11 +15,13 @@ jobs:
- php: 7.2
env: SKIP_INTEROP=true
- php: 7.2
- env: DEPENDENCIES='low'
+ env: COMPOSER_FLAGS='--prefer-lowest'
- php: 7.4
env: SYMFONY_VERSION='^4.4'
- php: nightly
- env: PHP8=true
+ env:
+ - PHP8=true
+ - COMPOSER_FLAGS='--ignore-platform-reqs'
before_install:
- phpenv config-rm xdebug.ini || echo "XDebug is not enabled"
@@ -27,8 +29,7 @@ before_install:
before_script:
- if [ "$SYMFONY_VERSION" != "" ]; then composer require --no-update "symfony/symfony:${SYMFONY_VERSION}"; fi;
- if [ "$SKIP_INTEROP" != "" ]; then composer remove --dev --no-update container-interop/container-interop; fi;
- - if [ "$DEPENDENCIES" != "low" ]; then composer update $([ -z "$PHP8" ] || echo "--ignore-platform-reqs") ; fi;
- - if [ "$DEPENDENCIES" = "low" ]; then composer update --prefer-lowest; fi;
+ - composer update $COMPOSER_FLAGS
- echo 'zend.exception_ignore_args=Off' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- export PATH=./bin:$PATH

original_message: Use COMPOSER_FLAGS in travis config


message: Handle different error message when class does not exist

diff:
@@ -438,8 +438,9 @@ EOL;
// Replace wrong warning message of HHVM
$output = str_replace('Notice: Undefined index: ', 'Notice: Undefined offset: ', $output);
- // replace error message that changed in PHP
+ // replace error messages that changed in PHP8
$output = str_replace('Warning: Undefined array key','Notice: Undefined offset:', $output);
+ $output = preg_replace('/Class "([^"]+)" not found/', 'Class \'$1\' not found', $output);
return trim(preg_replace("/ +$/m", '', $output));
}

diff:
@@ -22,7 +22,7 @@ use Error;
*/
abstract class ClassNotFoundHandler implements ExceptionHandler
{
- public const PATTERN = "/^Class '([^']+)' not found$/";
+ public const PATTERN = "/^Class (?:'|\")([^'\"]+)(?:'|\") not found$/";
/**
* {@inheritdoc}


message: More explicit null returns

diff:
@@ -223,15 +223,20 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
*/
private function getClassReflection() : closure
{
- return function (ReflectionParameter $parameter) {
+ return function (ReflectionParameter $parameter) : ?ReflectionClass
+ {
$t = $parameter->getType();
if ($t instanceof ReflectionNamedType) {
try {
return new ReflectionClass($t->getName());
}
- catch (\TypeError $t) {}
+ catch (\TypeError $t) {
+ return null;
+ }
}
+
+ return null;
};
}
}

original_message: More explicit null returns


message: Extra check when asking for the type

diff:
@@ -83,17 +83,17 @@ final class ArgumentAutowirer
return false;
}
- if (!$parameter->getType() instanceof ReflectionNamedType) {
- return false;
- }
-
return (bool) $this->getClassFromParameter($parameter);
}
private function getClassFromParameter(ReflectionParameter $parameter) : ?string
{
+ if (!($type = $parameter->getType()) || !($type instanceof ReflectionNamedType)) {
+ return null;
+ }
+
try {
- $typeString = $parameter->getType()->getName();
+ $typeString = $type->getName();
if ($typeString == 'self') {
return $parameter->getDeclaringClass()->getName();

original_message: Extra check when asking for the type


message: Fix line number in feature

diff:
@@ -148,6 +148,6 @@ Feature: Error Reporting
When an exception is thrown # features/exception_in_scenario.feature:7
Exception: Exception is thrown in features/bootstrap/FeatureContext.php:56
Stack trace:
- #0 src/Behat/Testwork/Call/Handler/RuntimeCallHandler.php(109): FeatureContext->anExceptionIsThrown()
+ #0 src/Behat/Testwork/Call/Handler/RuntimeCallHandler.php(110): FeatureContext->anExceptionIsThrown()
#1 src/Behat/Testwork/Call/Handler/RuntimeCallHandler.php(64): Behat\Testwork\Call\Handler\RuntimeCallHandler->executeCall(Object(Behat\Behat\Definition\Call\DefinitionCall))
"""

original_message: Fix line number in feature


message: Prepare for 3.8.0 release

diff:
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [3.8.0] - 2020-11-01
+
+### Added
+ * [1198](https://github.com/Behat/Behat/pull/1198): Korean language translations ([@getsolaris](https://github.com/getsolaris))
+ * [1252](https://github.com/Behat/Behat/pull/1252): Hungarian language translations ([@kolesar-andras](https://github.com/kolesar-andras))
+ * [1217](https://github.com/Behat/Behat/pull/1217): Bulgarian language translations ([@toni-kolev](https://github.com/toni-kolev))
+ * [1322](https://github.com/Behat/Behat/pull/1322): Feature title as classname in JUnit output ([@steefmin](https://github.com/steefmin))
+ * [1313](https://github.com/Behat/Behat/pull/1313): PHP 8 support ([@ciaranmcnulty](https://github.com/ciaranmcnulty))
+ * [1313](https://github.com/Behat/Behat/pull/1323): Further PHP 8 support ([@dgafka](https://github.com/dgafka))
+
+### Fixed
+
+ * [#1303](https://github.com/Behat/Behat/pull/1303): Error when running `--debug` with recent Symfony versions ([@jawira](https://github.com/jawira))
+ * [#1311](https://github.com/Behat/Behat/pull/1311): Remove symfony deprecation messages about transChoice ([@guilliamxavier](https://github.com/guilliamxavier))
+ * [#1318](https://github.com/Behat/Behat/pull/1318): Allow negated filters on scenario hoooks ([@andrewnicols ](https://github.com/andrewnicols))
+
+### Changed
+ * [#1299](https://github.com/Behat/Behat/pull/1299): Removed support for PHP <7.2, Symfony <4.4 ([@upamil](https://github.com/pamil))
+ * [#1310](https://github.com/Behat/Behat/pull/1310): Refactoring to use newer language features ([@rpkamp](https://github.com/rpkamp))
+ * [#1315](https://github.com/Behat/Behat/pull/1315): Remove BC layer for unsuppored symfony dispatcher ([@rpkamp](https://github.com/rpkamp))
+ * [#1314](https://github.com/Behat/Behat/pull/1314): Remove BC layer for unsuppored symfony translator ([@rpkamp](https://github.com/rpkamp))
+ * [#1212](https://github.com/Behat/Behat/pull/1212): Updated composer description ([@tkotosz](https://github.com/tkotosz))
+ * [#1317](https://github.com/Behat/Behat/pull/1317): Use PHPUnit8 for unit testing ([@phil-davis](https://github.com/phil-davis))
+
## [3.7.0] - 2020-06-03
### Added

diff:
@@ -46,7 +46,7 @@ use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
*/
final class ApplicationFactory extends BaseFactory
{
- public const VERSION = '3.7.0';
+ public const VERSION = '3.8.0';
/**
* {@inheritdoc}

original_message: Prepare for 3.8.0 release


message: Reproducer that triggers error

diff:
@@ -674,3 +674,36 @@ Feature: Step Arguments Transformations
"""
string given
"""
+
+ Scenario: Return type transformations don't cause issues with scalar type hints (regression)
+ Given a file named "features/scalar-transforms.feature" with:
+ """
+ Feature:
+
+ Scenario:
+ Then "string" should be passed
+ """
+ And a file named "features/bootstrap/FeatureContext.php" with:
+ """
+ <?php
+
+ class FeatureContext implements Behat\Behat\Context\Context
+ {
+ /**
+ * @Transform
+ */
+ public function transformToFoo($input): Foo
+ {
+ }
+
+ /**
+ * @Then :string should be passed
+ */
+ public function doSomething(string $job)
+ {
+
+ }
+ }
+ """
+ When I run "behat -f progress --no-colors"
+ Then it should pass

original_message:
Reproducer that triggers error

Co-authored-by: Adam Quaile <adamquaile@gmail.com>


message: Catch the correct Exception when matching return type transforms

diff:
@@ -17,6 +17,7 @@ use Behat\Testwork\Call\CallCenter;
use Behat\Testwork\Call\RuntimeCallee;
use Closure;
use ReflectionClass;
+use ReflectionException;
use ReflectionFunctionAbstract;
use ReflectionMethod;
use ReflectionParameter;
@@ -231,7 +232,7 @@ final class ReturnTypeTransformation extends RuntimeCallee implements SimpleArgu
try {
return new ReflectionClass($t->getName());
}
- catch (\TypeError $t) {
+ catch (ReflectionException $t) {
return null;
}
}


message: Ready for 3.8.1 release

diff:
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [3.8.1] - 2020-11-07
+
+### Fixed
+
+ * [1329](https://github.com/Behat/Behat/pull/1329): Regression when using scalar type hints ([@ciaranmcnulty](https://github.com/ciaranmcnulty))
+
## [3.8.0] - 2020-11-01
### Added

diff:
@@ -46,7 +46,7 @@ use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
*/
final class ApplicationFactory extends BaseFactory
{
- public const VERSION = '3.8.0';
+ public const VERSION = '3.8.1';
/**
* {@inheritdoc}

original_message: Ready for 3.8.1 release


message:
Fix syntax help test and bump gherkin dependency
The change in the sort order of the translations broke this test

diff:
@@ -11,7 +11,7 @@ Feature: Syntax helpers
When I run "behat --no-colors --story-syntax"
Then the output should contain:
"""
- [Business Need|Feature|Ability]: Internal operations
+ [Business Need|Ability|Feature]: Internal operations
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory


message: Automerge script

diff:
+name: 'Up merge'
+
+on:
+ push:
+ branches: [ master ]
+
+jobs:
+ nightly-merge:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Up Merge
+ uses: bambamboole/gha-upmerge@master
+ with:
+ stable_branch: 'master'
+ development_branch: '4.x'

original_message: Automerge script


message: Fix automerge GHA branch

diff:
@@ -14,7 +14,7 @@ jobs:
uses: actions/checkout@v2
- name: Up Merge
- uses: bambamboole/gha-upmerge@master
+ uses: bambamboole/gha-upmerge@main
with:
stable_branch: 'master'
development_branch: '4.x'

original_message: Fix automerge GHA branch


message: Fix GHA upmerge field names

diff:
@@ -16,5 +16,5 @@ jobs:
- name: Up Merge
uses: bambamboole/gha-upmerge@main
with:
- stable_branch: 'master'
- development_branch: '4.x'
+ from_branch: 'master'
+ to_branch: '4.x'

original_message: Fix GHA upmerge field names


message: Remove failed merge-up script

change_type: DELETE

diff:
-name: 'Up merge'
-
-on:
- push:
- branches: [ master ]
-
-jobs:
- nightly-merge:
-
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Up Merge
- uses: bambamboole/gha-upmerge@main
- with:
- from_branch: 'master'
- to_branch: '4.x'
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

original_message: Remove failed merge-up script


message: Suppress false-positive static analysis issues

diff:
</errorLevel>
</InvalidThrow>
+ <!-- suppress errors related to Symfony return types including enums -->
+ <UndefinedDocblockClass>
+ <errorLevel type="suppress">
+ <referencedClass name="UnitEnum" />
+ </errorLevel>
+ </UndefinedDocblockClass>
+
<!-- Suppress errors related to legacy PHPUnit classes -->
<UndefinedClass>
<errorLevel type="suppress">

diff:
@@ -58,6 +58,9 @@ final class DefinitionAttributeReader implements AttributeReader
return [];
}
+ /**
+ * @psalm-suppress UndefinedClass (ReflectionAttribute is PHP 8.0 only)
+ */
$attributes = $method->getAttributes(Definition::class, \ReflectionAttribute::IS_INSTANCEOF);
$callees = [];

diff:
@@ -59,6 +59,9 @@ final class HookAttributeReader implements AttributeReader
return [];
}
+ /**
+ * @psalm-suppress UndefinedClass (ReflectionAttribute is PHP 8.0 only)
+ */
$attributes = $method->getAttributes(Hook::class, \ReflectionAttribute::IS_INSTANCEOF);
$callees = [];

diff:
@@ -241,6 +241,9 @@ final class MixedArgumentOrganiser implements ArgumentOrganiser
$type = $parameter->getType();
+ /**
+ * @psalm-suppress UndefinedClass (ReflectionUnionType)
+ */
if ($type instanceof \ReflectionNamedType) {
$types = [$type];
}

diff:
@@ -55,6 +55,10 @@ final class SigintController implements Controller
{
if (function_exists('pcntl_signal')) {
pcntl_async_signals(true);
+
+ /**
+ * @psalm-suppress UndefinedConstant (SIGINT is defined in pcntl)
+ */
pcntl_signal(SIGINT, array($this, 'abortExercise'));
}
}


message: Run GHA on windows

diff:
@@ -10,7 +10,7 @@ on:
jobs:
tests:
- runs-on: ubuntu-latest
+ runs-on: ${{ matrix.os }}
name: Build and test
strategy:
fail-fast: false
@@ -18,19 +18,31 @@ jobs:
include:
- php: 7.2
publish-phar: true
+ os: ubuntu-latest
- php: 7.2
skip-interop: true
+ os: ubuntu-latest
- php: 7.2
composer-flags: --prefer-lowest
+ os: ubuntu-latest
- php: 7.3
+ os: ubuntu-latest
- php: 7.4
+ os: ubuntu-latest
- php: 7.4
SYMFONY_REQUIRE: 4.4.*
+ os: ubuntu-latest
- php: 8.0
+ os: ubuntu-latest
- php: 8.0
stability: dev
SYMFONY_REQUIRE: 6.0.*
+ os: ubuntu-latest
+ - php: 8.1
+ os: windows-latest
- php: 8.1
+ os: ubuntu-latest
+
steps:
- uses: actions/checkout@v2

original_message: Run GHA on windows


message: Run tests on MacOS

diff:
@@ -38,6 +38,8 @@ jobs:
stability: dev
SYMFONY_REQUIRE: 6.0.*
os: ubuntu-latest
+ - php: 8.1
+ os: macos-latest
- php: 8.1
os: windows-latest
- php: 8.1

original_message: Run tests on MacOS


message: Drop Appveyor

diff:
-version: '{build}'
-build: false
-shallow_clone: false
-platform: x86
-clone_folder: c:\projects\behat
-
-branches:
- only:
- - master
-
-skip_commits:
- message: /\[ci skip\]/
-
-cache:
- - C:\ProgramData\chocolatey\bin -> appveyor.yml
- - C:\ProgramData\chocolatey\lib -> appveyor.yml
- - C:\tools\php -> appveyor.yml
- - C:\tools\composer -> appveyor.yml
- - '%LOCALAPPDATA%\Composer\files'
-
-init:
- - SET PATH=C:\Program Files\OpenSSL;c:\tools\php;C:\tools\composer;%PATH%
- - SET COMPOSER_NO_INTERACTION=1
- - SET ANSICON=121x90 (121x90)
- - git config --global core.autocrlf input
-
-install:
- - ps: |
- if (!(Test-Path c:\tools\php)) {
- appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version 7.2
- Get-ChildItem -Path c:\tools\php
- cd c:\tools\php
-
- # Set PHP environment items that are always needed
- copy php.ini-production php.ini
- Add-Content php.ini "`n date.timezone=UTC"
- Add-Content php.ini "`n extension_dir=ext"
- Add-Content php.ini "`n extension=php_openssl.dll"
- Add-Content php.ini "`n extension=php_curl.dll"
- Add-Content php.ini "`n extension=php_mbstring.dll"
- Add-Content php.ini "`n extension=php_fileinfo.dll"
- Add-Content php.ini "`n zend.exception_ignore_args=Off"
-
- # download Composer
- if (!(Test-Path C:\tools\composer)) {
- New-Item -path c:\tools -name composer -itemtype directory
- }
-
- if (!(Test-Path c:\tools\composer\composer.phar)) {
- appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar -Filename C:\tools\composer\composer.phar
- Set-Content -path 'C:\tools\composer\composer.bat' -Value ('@php C:\tools\composer\composer.phar %*')
- }
- }
-
- - cd c:\projects\behat
- - appveyor-retry composer self-update
- - appveyor-retry composer install --no-progress --ansi
-
-test_script:
- - cd c:\projects\behat
- - php bin\behat --format=progress
- - php vendor\phpunit\phpunit\phpunit --testdox

original_message: Drop Appveyor


message: Use less bash in the gha to avoid confusing windows

diff:
@@ -79,7 +79,11 @@ jobs:
run: ./vendor/bin/phpunit
- name: Run tests (Behat)
- run: ./bin/behat -fprogress --strict $([ -z "${{ matrix.skip-interop }}" ] || echo "--tags ~@interop&&~@php8")
+ run: ./bin/behat -fprogress --strict --tags="~@interop&&~@php8"
+
+ - name: Run tests (Behat with Interop)
+ if: matrix.skip-interop != true
+ run: ./bin/behat -fprogress --strict --tags=@interop
- name: Run tests (Behat for PHP 8.0)
if: matrix.php >= 8.0


message: Set default shell to bash

diff:
@@ -11,6 +11,9 @@ on:
jobs:
tests:
runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ shell: bash
name: Build and test
strategy:
fail-fast: false

original_message: Set default shell to bash


message: Fix JUnit printer to use realpath when comparing folders

diff:
@@ -84,9 +84,10 @@ final class JUnitScenarioPrinter
);
if ($file) {
+ $cwd = realpath(getcwd());
$testCaseAttributes['file'] =
- substr($file, 0, strlen(getcwd())) === getcwd() ?
- ltrim(substr($file, strlen(getcwd())), DIRECTORY_SEPARATOR) : $file;
+ substr($file, 0, strlen($cwd)) === $cwd ?
+ ltrim(substr($file, strlen($cwd)), DIRECTORY_SEPARATOR) : $file;
}
$outputPrinter->addTestcase($testCaseAttributes);


message: 3.11.0 release

diff:
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [3.11.0] - 2022-07-07
+
+### Added
+* [#1387](https://github.com/Behat/Behat/pull/1387) Added file attribute to Junit output [@ppaulis](https://github.com/ppaulis)
+* [#1266](https://github.com/Behat/Behat/pull/1266) Enable env placeholder resolution in config [@mpdude](https://github.com/mpdude)
+* [#1380](https://github.com/Behat/Behat/pull/1380) Support psr/container 2.0 [@wouterj](https://github.com/wouterj)
+* [#1340](https://github.com/Behat/Behat/pull/1340) Added Chinese language [@54853315](https://github.com/54853315)
+
+### Fixed
+* [#1374](https://github.com/Behat/Behat/pull/1374) Fixed counts in hu translations [@Sweetchuck](https://github.com/Sweetchuck)
+* [#1393](https://github.com/Behat/Behat/pull/1393) Fixed counts in bg and jo translations [@delyro](https://github.com/delyro)
+
+### Other contributions
+* [#1398](https://github.com/Behat/Behat/pull/1398) Fix failing builds due to composer --allow-plugins [@Chekote](https://github.com/Chekote)
+
## 3.10.0 - 2021-11-02
## What's Changed
@@ -983,7 +998,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed
* Initial release
-[Unreleased]: https://github.com/Behat/Behat/compare/v3.9.0...master
+[3.11.0]: https://github.com/Behat/Behat/compare/v3.10.0...v3.11.0
[3.9.0]: https://github.com/Behat/Behat/compare/v3.8.1...v3.9.0
[3.8.1]: https://github.com/Behat/Behat/compare/v3.8.0...v3.8.1
[3.8.0]: https://github.com/Behat/Behat/compare/v3.7.0...v3.8.0

diff:
@@ -46,7 +46,7 @@ use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
*/
final class ApplicationFactory extends BaseFactory
{
- public const VERSION = '3.8.1';
+ public const VERSION = '3.11.0';
/**
* {@inheritdoc}

original_message: 3.11.0 release


message: Don't always install symfony/flex / add separate symfony LTS jobs

diff:
@@ -18,33 +18,49 @@ jobs:
strategy:
fail-fast: false
matrix:
+ php: [7.2, 7.3, 7.4, 8.0, 8.1]
+ os: [ubuntu-latest]
+ composer-mode: [update]
+ symfony-version: ['']
include:
+ # Get the existing 7.2 to publish the phar
- php: 7.2
- publish-phar: true
os: ubuntu-latest
+ composer-mode: update
+ publish-phar: true
+ symfony-version: ''
+
+ # 7.2 build with lowest dependencies
- php: 7.2
- composer-flags: --prefer-lowest
- os: ubuntu-latest
- - php: 7.3
- os: ubuntu-latest
- - php: 7.4
- os: ubuntu-latest
- - php: 7.4
- SYMFONY_REQUIRE: 4.4.*
- os: ubuntu-latest
- - php: 8.0
- os: ubuntu-latest
- - php: 8.0
- stability: dev
- SYMFONY_REQUIRE: 6.0.*
os: ubuntu-latest
+ composer-mode: lowest
+ symfony-version: ''
+
+ # MacOS on latest PHP only
- php: 8.1
os: macos-latest
+ composer-mode: update
+ symfony-version: ''
+
+ # Windows on latest PHP only
- php: 8.1
os: windows-latest
+ composer-mode: update
+ symfony-version: ''
+
+ # Symfony jobs:
- php: 8.1
os: ubuntu-latest
-
+ composer-mode: update
+ symfony-version: '4.4'
+ - php: 8.1
+ os: ubuntu-latest
+ composer-mode: update
+ symfony-version: '5.4'
+ - php: 8.1
+ os: ubuntu-latest
+ composer-mode: update
+ symfony-version: '6.0'
steps:
- uses: actions/checkout@v2
@@ -56,22 +72,21 @@ jobs:
ini-values: "phar.readonly=0,zend.exception_ignore_args=Off"
coverage: none
- - name: Configure Composer minimum stability
- if: matrix.stability
- run: composer config minimum-stability ${{ matrix.stability }}
-
- name: Install symfony/flex
+ if: matrix.symfony-version != ''
run: |
composer config --global --no-plugins allow-plugins.symfony/flex true &&
composer global require symfony/flex
- - name: Uninstall Psalm
- run: composer remove --dev --no-update vimeo/psalm
-
- - name: Install dependencies
+ - name: Install latest dependencies
+ if: matrix.composer-mode == 'update'
env:
- SYMFONY_REQUIRE: "${{ matrix.SYMFONY_REQUIRE }}"
- run: composer update ${{ matrix.composer-flags }}
+ SYMFONY_REQUIRE: ${{ matrix.symfony-version }}.*
+ run: composer update
+
+ - name: Install lowest dependencies
+ if: matrix.composer-mode == 'lowest'
+ run: composer update --prefer-lowest
- name: Run tests (phpunit)
run: ./vendor/bin/phpunit
@@ -84,7 +99,7 @@ jobs:
run: ./bin/behat -fprogress --strict --tags=@php8
- name: Build the PHAR
- if: matrix.php != '8.0'
+ if: matrix.publish-phar == true
run: |
curl -LSs https://box-project.github.io/box2/installer.php | php &&
export PATH=.:$PATH &&
@@ -94,14 +109,14 @@ jobs:
- uses: actions/upload-artifact@v1
name: Publish the PHAR
- if: matrix.publish-phar
+ if: matrix.publish-phar == true
with:
name: behat.phar
path: behat.phar
- psalm:
+ static-analysis:
runs-on: ubuntu-latest
- name: Psalm (PHP 8.0)
+ name: Static analysis
steps:
- uses: actions/checkout@v2
@@ -109,7 +124,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
- ini-values: "phar.readonly=0,zend.exception_ignore_args=Off"
+ ini-values: "zend.exception_ignore_args=Off"
coverage: none
- name: Install dependencies
@@ -120,7 +135,7 @@ jobs:
publish-phar:
runs-on: ubuntu-latest
- name: Publish the PHAR
+ name: Publish the PHAR for release
needs: tests
if: github.event_name == 'release'
steps:


message: Remove Scrutiniser and Appveyor badges

diff:
@@ -4,9 +4,7 @@ Behat is a BDD framework for PHP to help you test business expectations.
[![Gitter chat](https://badges.gitter.im/Behat/Behat.svg)](https://gitter.im/Behat/Behat)
[![License](https://poser.pugx.org/behat/behat/license.svg)](https://packagist.org/packages/behat/behat)
-[![Unix Status](https://github.com/Behat/Behat/workflows/Build/badge.svg)](https://github.com/Behat/Behat/actions?query=workflow%3ABuild)
-[![Windows status](https://ci.appveyor.com/api/projects/status/9uc5sellmvbv02ei/branch/master?svg=true)](https://ci.appveyor.com/project/everzet/behat/branch/master)
-[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/Behat/Behat/badges/quality-score.png?s=ad84e95fc2405712f88a96d89b4f31dfe5c80fae)](https://scrutinizer-ci.com/g/Behat/Behat/)
+[![Build Status](https://github.com/Behat/Behat/workflows/Build/badge.svg)](https://github.com/Behat/Behat/actions?query=workflow%3ABuild)
Installing Behat
----------------

original_message: Remove Scrutiniser and Appveyor badges (#1402)


message: Add prophecy dependency

original_message: Add prophecy dependency


message: Add PHP 8.2 to the test grid

diff:
@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- php: [7.2, 7.3, 7.4, 8.0, 8.1]
+ php: [7.2, 7.3, 7.4, 8.0, 8.1, 8.2]
os: [ubuntu-latest]
composer-mode: [update]
symfony-version: ['']
@@ -37,27 +37,27 @@ jobs:
symfony-version: ''
# MacOS on latest PHP only
- - php: 8.1
+ - php: 8.2
os: macos-latest
composer-mode: update
symfony-version: ''
# Windows on latest PHP only
- - php: 8.1
+ - php: 8.2
os: windows-latest
composer-mode: update
symfony-version: ''
# Symfony jobs:
- - php: 8.1
+ - php: 8.2
os: ubuntu-latest
composer-mode: update
symfony-version: '4.4'
- - php: 8.1
+ - php: 8.2
os: ubuntu-latest
composer-mode: update
symfony-version: '5.4'
- - php: 8.1
+ - php: 8.2
os: ubuntu-latest
composer-mode: update
symfony-version: '6.0'
@@ -123,7 +123,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
- php-version: 8.0
+ php-version: 8.2
ini-values: "zend.exception_ignore_args=Off"
coverage: none

original_message: Add PHP 8.2 to the test grid


message: Update changelog for 3.12.0 release

diff:
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [3.12.0] - 2022-11-29
+
+### Added
+* [#1417](https://github.com/Behat/Behat/pull/1417) Allow install with PHP 8.2 [@ciaranmcnulty](https://github.com/ciaranmcnulty)
+
+### Fixed
+* [#1412](https://github.com/Behat/Behat/pull/1412) Fix dynamic property deprecation notices in PHP 8.2 [@gquemener](https://github.com/gquemener)
+* [#1410](https://github.com/Behat/Behat/pull/1410) Fix deprecation errors in Junit formatter for PHP 8.1 [@albeorte96](https://github.com/albeorte96)
+
+### Other contributions
+* [#1415](https://github.com/Behat/Behat/pull/1415) Fix README typo [@vinceAmstoutz](https://github.com/vinceAmstoutz)
+
## [3.11.0] - 2022-07-07
### Added
@@ -998,6 +1010,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed
* Initial release
+[3.12.0]: https://github.com/Behat/Behat/compare/v3.11.0...v3.12.0
[3.11.0]: https://github.com/Behat/Behat/compare/v3.10.0...v3.11.0
[3.9.0]: https://github.com/Behat/Behat/compare/v3.8.1...v3.9.0
[3.8.1]: https://github.com/Behat/Behat/compare/v3.8.0...v3.8.1

original_message: Update changelog for 3.12.0 release


message: Update version number for 3.12.0 release

diff:
@@ -46,7 +46,7 @@ use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
*/
final class ApplicationFactory extends BaseFactory
{
- public const VERSION = '3.11.0';
+ public const VERSION = '3.12.0';
/**
* {@inheritdoc}


message: style pass search input

diff:
};
</script>
-<style>
+<style lang="scss">
input {
- background: url("/mag-glass.svg") 10px center / 20px 20px no-repeat
- rgb(255, 255, 255);
+ background: url("/mag-glass.svg") 10px center / 24px 24px no-repeat
+ var(--white);
+ box-shadow: var(--shadow);
+ height: var(--small);
+ font-size: var(--p-medium);
}
:global(.algolia-autocomplete) {
type="search"
placeholder="Search"
id={docSearchInputSelector}
- class="block w-full pl-10 pr-3 py-2 border border-transparent rounded-md leading-5 bg-white text-gray-600 placeholder-gray-400 focus:outline-none focus:bg-white focus:border-white focus:ring-white focus:text-gray-900 sm:text-sm"
+ class="block w-full pl-16 pr-3 py-4 border border-transparent rounded-3xl leading-5 bg-white text-gray-600 placeholder-gray-500 focus:outline-none focus:bg-white focus:border-white focus:ring-white focus:text-gray-900"
/>
</div>
</div>

repo: gitpod-io/website

original_message: style pass search input


message: remove edit in gitpod button as per figma

diff:
<Search />
- <EditInGitpodButton />
+
<slot />


message: initial style pass of docs content

diff:
$: $docsCurrentSectionStore = section;
</script>
-<style>
- .content :global(blockquote) {
- @apply my-14 p-8 rounded-lg bg-orange-700;
+<style lang="scss">
+ @mixin h3 {
+ font-size: var(--p-large);
+ line-height: 3.2rem;
}
- .content :global(blockquote code) {
- @apply p-2 rounded-lg bg-orange-900;
+ .content {
+ // Typography
+ :global(h1),
+ :global(h2),
+ :global(h3) {
+ margin-bottom: var(--xx-small);
+ font-weight: 700;
}
- .content :global(code) {
- @apply p-2 rounded-lg bg-orange-700;
+ :global(h1) {
+ font-size: 4.8rem;
+ line-height: 5.6rem;
}
- .content :global(pre) {
- @apply p-8 rounded-lg bg-gray-300 overflow-x-scroll;
- }
+ :global(h2) {
+ font-size: var(--h4);
+ line-height: 4rem;
- .content :global(pre code) {
- @apply bg-transparent;
+ &.h3 {
+ @include h3;
+ }
}
- .content :global(h1) {
- @apply text-h1;
+ :global(h3) {
+ @include h3;
}
- .content :global(h2) {
- @apply text-h2;
+ :global(h3 em) {
+ font-style: normal;
}
- .content :global(h3) {
- @apply text-h3;
+ :global(p + h3),
+ :global(p + .h3) {
+ margin-top: 8.8rem;
}
- .content :global(h4) {
- @apply text-h4;
+ // Video
+ :global(p > iframe) {
+ margin: var(--medium) 0;
}
- .content :global(h5) {
- @apply text-h5;
+ // Code blocks
+ :global(code) {
+ min-height: 3.2rem;
+ padding: 0 0.8rem;
+ border-radius: 1.2rem;
+ background: var(--brand-light);
+
+ &:not([class]) {
+ display: inline-flex;
+ align-items: center;
}
- .content :global(h6) {
- @apply text-h6;
+ &.language-null {
+ display: block;
+ padding: 2rem 2.4rem;
+ background: var(--sand-dark);
+ }
}
- .content :global(p) {
- @apply my-8;
+ :global(blockquote) {
+ margin: 3.2rem 0;
+ padding: 2.4rem;
+ border-radius: 1.2rem;
+ background: var(--brand-light);
+
+ :global(code) {
+ background: var(--brand-almost-ripe);
+ }
+ }
}
</style>

original_message: initial style pass of docs content


message: side menu styling pass

diff:
</script>

-

- <MenuLink href={menuItem.path} class="leading-loose text-h6"
- >{menuItem.title}</MenuLink
- >
- {#if menuItem.subMenu}
-

+

+ <MenuLink href={menuItem.path} class="text-h6">{menuItem.title}</MenuLink>
+ {#if menuItem.subMenu && isActiveSection}
+

{#each menuItem.subMenu as sub}

<MenuLink href={sub.path}>{sub.title}</MenuLink>

original_message: side menu styling pass


message: more content typography styling

diff:
font-style: normal;
}
+ :global(p + h2),
+ :global(h2 ~ h2) {
+ margin-top: var(--medium);
+ }
+
:global(p + h3),
- :global(p + .h3) {
+ :global(p + .h3),
+ :global(h3 ~ h3),
+ :global(h3 ~ .h3) {
margin-top: 8.8rem;
}
// Video
:global(p > iframe) {
- margin: var(--medium) 0;
+ margin-top: var(--medium);
}
// Code blocks
align-items: center;
}
- &.language-null {
+ &.language-null,
+ &.language-text {
display: block;
padding: 2rem 2.4rem;
background: var(--sand-dark);

original_message: more content typography styling


message: capture all types of code block styling

diff:
align-items: center;
}
- &.language-null,
- &.language-text {
+ &[class*="language"] {
display: block;
padding: 2rem 2.4rem;
background: var(--sand-dark);

original_message: capture all types of code block styling


message: more typography updates and initial table styles

diff:
@include h3;
}
+ :global(a) {
+ font-weight: 700;
+
+ &:hover {
+ color: var(--brand-ripe);
+ }
+ }
+
:global(h3 em) {
font-style: normal;
}
+ // Spacing
:global(p + h2),
:global(h2 ~ h2) {
margin-top: var(--medium);
margin-top: 8.8rem;
}
- // Video
+ :global(p + p) {
+ margin-top: var(--micro);
+ }
+
:global(p > iframe) {
margin-top: var(--medium);
}
+ :global(li + li) {
+ margin-top: var(--macro);
+ }
+
// Code blocks
:global(code) {
min-height: 3.2rem;
}
&[class*="language"] {
+ overflow: auto;
display: block;
padding: 2rem 2.4rem;
background: var(--sand-dark);
}
}
+ :global(pre) {
+ margin: var(--micro) 0;
+ }
+
:global(blockquote) {
margin: 3.2rem 0;
padding: 2.4rem;
background: var(--brand-almost-ripe);
}
}
+
+ :global(table) {
+ border-radius: 1.6rem;
+ overflow: hidden;
+ }
+
+ :global(thead) {
+ background: var(--sand-dark);
+ }
+
+ :global(tbody) {
+ background: var(--offwhite);
+ }
}
</style>


message: more docs + table styling pass

diff:
font-size: var(--h4);
line-height: 4rem;
- .h3 {
+ &.h3 {
@include h3;
}
}
}
// Spacing
- p + h2,
- h2 ~ h2 {
+ * + h2 {
margin-top: var(--medium);
}
- p + h3,
- p + .h3,
- h3 ~ h3,
- h3 ~ .h3 {
- margin-top: 8.8rem;
+ * + h3,
+ * + .h3 {
+ margin-top: var(--large);
}
- p + p {
+ h4 {
+ margin-bottom: var(--macro);
+ }
+
+ p + h4,
+ h4 ~ h4 {
+ margin-top: var(--xx-small);
+ }
+
+ p + p,
+ p + ul,
+ ul + p {
margin-top: var(--micro);
}
margin-top: var(--medium);
}
+ ol,
+ ul {
+ margin: var(--micro) 0;
+ }
+
li + li {
margin-top: var(--macro);
}
padding: 2rem 2.4rem;
background: var(--sand-dark);
}
+
+ &.language-Dockerfile {
+ background: var(--off-white);
+ }
}
pre {
}
table {
- border-radius: 1.6rem;
+ width: 100%;
+ margin: var(--micro) 0;
overflow: hidden;
+ border-radius: 1.6rem;
+ font-size: var(--p-small);
}
thead {
}
tbody {
- background: var(--offwhite);
+ background: var(--off-white);
+ }
+
+ th,
+ td {
+ @apply py-5 px-10;
+ @apply text-left;
+ }
+
+ td {
+ @apply py-6;
+ }
+
+ th {
+ @apply font-normal;
+ }
+
+ td:first-child {
+ @apply font-bold;
+ @apply align-top;
+ }
+
+ th + th,
+ td + td {
+ @apply border-l border-solid border-gray-400;
+ }
+
+ tr + tr {
+ // border-top: 1px solid
+ @apply border-t border-solid border-gray-400;
}
}

original_message: more docs + table styling pass


message: Adjust classes for spacing

diff:
}
.submenu {
+ @apply ml-6 mt-4;
font-size: var(--p-medium);
line-height: var(--x-small);
}

<MenuLink href={menuItem.path} class="text-h6">{menuItem.title}</MenuLink>
{#if menuItem.subMenu && isActiveSection}
-

+

{#each menuItem.subMenu as sub}

<MenuLink href={sub.path}>{sub.title}</MenuLink>

diff:
];
</script>
+
+

-

+

{#each MENU as menuItem}
<MenuSection {menuItem} />
{/each}

diff:
src="https://cdn.jsdelivr.net/npm/docsearch.js@{docSearchJSVersion}/dist/cdn/docsearch.min.js"></script>
</svelte:head>
-

+

Search

<input
type="search"
placeholder="Search"
id={docSearchInputSelector}
- class="block w-full pl-16 pr-3 py-4 border border-transparent rounded-3xl leading-5 bg-white text-gray-600 placeholder-gray-500 focus:outline-none focus:bg-white focus:border-white focus:ring-white focus:text-gray-900"
+ class="block w-full pl-11 pr-3 py-2 border border-transparent rounded-3xl leading-5 bg-white text-gray-600 placeholder-gray-500 focus:outline-none focus:bg-white focus:border-white focus:ring-white focus:text-gray-900"
/>

diff:
import Search from "../../components/docs/search.svelte";
</script>
-

+

<Menu />

original_message: Adjust classes for spacing


message: Adjust menu spacing

diff:
<style>
.menu-item {
- padding: 0 var(--xx-small);
+ @apply px-6;
font-size: var(--p-large);
}
.submenu {
- @apply ml-6 mt-4;
+ @apply ml-4 mt-4;
font-size: var(--p-medium);
line-height: var(--x-small);
}
.isActiveSection {
@apply bg-white;
- @apply py-9;
+ @apply py-6;
border-radius: 1.6rem;
box-shadow: var(--shadow);
}

original_message: Adjust menu spacing


message: more layout adjustments to match updated figma designs

diff:
tr + tr {
@apply border-t border-solid border-gray-400;
}
+
+ iframe {
+ width: 100%;
+ }
}

diff:
--micro: 1rem; /* should we invert micro and macro? */
--macro: 0.5rem;
- --shadow: 0rem 1rem 2.4rem 0rem rgba(0, 0, 0, 0.08);
+ --shadow: 0rem 0.625rem 1.5rem 0rem rgba(0, 0, 0, 0.08);
--border-light: 1px solid var(--sand-dark);

diff:
.isActiveSection {
@apply bg-white;
@apply py-6;
- border-radius: 1.6rem;
+ border-radius: 1rem;
box-shadow: var(--shadow);
}
</style>

diff:
type="search"
placeholder="Search"
id={docSearchInputSelector}
- class="block w-full pl-11 pr-3 py-2 border border-transparent rounded-3xl leading-5 bg-white text-gray-600 placeholder-gray-500 focus:outline-none focus:bg-white focus:border-white focus:ring-white focus:text-gray-900"
+ class="block w-full pl-11 pr-3 py-2 border border-transparent rounded-xl leading-5 bg-white text-gray-600 placeholder-gray-500 focus:outline-none focus:bg-white focus:border-white focus:ring-white focus:text-gray-900"
/>
</div>
</div>

diff:
import Search from "../../components/docs/search.svelte";
</script>
-

-

+

+

<Menu />