Skip to content

Commit 593fa99

Browse files
committed
Merge branch 'release-v66.0.1' into release
2 parents 8c3405a + 4d0cc3e commit 593fa99

File tree

31 files changed

+253
-146
lines changed

31 files changed

+253
-146
lines changed

.buildconfig.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
libraryVersion: 66.0.0
1+
libraryVersion: 66.0.1
22
groupId: org.mozilla.telemetry
33
projects:
44
glean:

.circleci/config.yml

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,24 @@ jobs:
438438
- image: cimg/android:2025.10.1-browsers
439439
steps:
440440
- checkout
441+
- run:
442+
name: Check if Kotlin files have been touched
443+
command: |
444+
DEFAULT_BRANCH=main
445+
COMMIT_RANGE="${DEFAULT_BRANCH}...${CIRCLE_SHA1}"
446+
echo "commit range: ${COMMIT_RANGE}"
447+
echo "Changed files:"
448+
changed_files=$(git diff --name-only $COMMIT_RANGE)
449+
echo "$changed_files"
450+
451+
if echo "$changed_files" | grep -E '.kt$'; then
452+
changed_kotlin_count=$(echo "$changed_files" | grep -E '.kt$' -c)
453+
echo "Count of changed kotlin files: $changed_kotlin_count"
454+
else
455+
echo "No Kotlin files touched. No need for linting."
456+
circleci-agent step halt
457+
fi
458+
441459
- android-setup
442460
- run: ./gradlew --no-daemon lint
443461
- run: ./gradlew --no-daemon ktlint
@@ -499,7 +517,7 @@ jobs:
499517
Check Swift formatting:
500518
macos:
501519
xcode: "16.4"
502-
resource_class: "macos.m1.medium.gen1"
520+
resource_class: "m4pro.medium"
503521
steps:
504522
- checkout
505523
- run:
@@ -517,7 +535,7 @@ jobs:
517535
iOS build and test:
518536
macos:
519537
xcode: "16.4"
520-
resource_class: "macos.m1.medium.gen1"
538+
resource_class: "m4pro.medium"
521539
steps:
522540
- checkout
523541
- run:
@@ -618,7 +636,7 @@ jobs:
618636
iOS integration test:
619637
macos:
620638
xcode: "16.4"
621-
resource_class: "macos.m1.medium.gen1"
639+
resource_class: "m4pro.medium"
622640
steps:
623641
- checkout
624642
- skip-if-doc-only
@@ -663,7 +681,7 @@ jobs:
663681
iOS Framework release:
664682
macos:
665683
xcode: "16.4"
666-
resource_class: "macos.m1.medium.gen1"
684+
resource_class: "m4pro.medium"
667685
steps:
668686
- checkout
669687
- attach_workspace:
@@ -902,7 +920,7 @@ jobs:
902920
pypi-macos-release:
903921
macos:
904922
xcode: "16.4"
905-
resource_class: "macos.m1.medium.gen1"
923+
resource_class: "m4pro.medium"
906924
steps:
907925
- install-rustup
908926
- setup-rust-toolchain

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# Unreleased changes
22

3-
[Full changelog](https://github.com/mozilla/glean/compare/v66.0.0...main)
3+
[Full changelog](https://github.com/mozilla/glean/compare/v66.0.1...main)
4+
5+
# v66.0.1 (2025-10-30)
6+
7+
[Full changelog](https://github.com/mozilla/glean/compare/v66.0.0...v66.0.1)
8+
9+
* Swift
10+
* Rely on `Codable` again for serialization of object metrics ([#3300](https://github.com/mozilla/glean/pull/3300))
411

512
# v66.0.0 (2025-10-20)
613

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

DEPENDENCIES.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4606,9 +4606,9 @@ SOFTWARE.
46064606

46074607
The following text applies to code linked from these dependencies:
46084608

4609-
* [glean-core 66.0.0]( https://github.com/mozilla/glean )
4610-
* [glean-build 18.0.2]( https://github.com/mozilla/glean )
4611-
* [glean 66.0.0]( https://github.com/mozilla/glean )
4609+
* [glean-core 66.0.1]( https://github.com/mozilla/glean )
4610+
* [glean-build 18.0.6]( https://github.com/mozilla/glean )
4611+
* [glean 66.0.1]( https://github.com/mozilla/glean )
46124612
* [zeitstempel 0.2.0]( https://github.com/badboy/zeitstempel )
46134613

46144614
```

glean-core/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "glean-core"
3-
version = "66.0.0"
3+
version = "66.0.1"
44
authors = ["Jan-Erik Rediger <[email protected]>", "The Glean Team <[email protected]>"]
55
description = "A modern Telemetry library"
66
repository = "https://github.com/mozilla/glean"
@@ -21,7 +21,7 @@ include = [
2121
rust-version = "1.82"
2222

2323
[package.metadata.glean]
24-
glean-parser = "18.0.2"
24+
glean-parser = "18.0.6"
2525

2626
[badges]
2727
circle-ci = { repository = "mozilla/glean", branch = "main" }

glean-core/build/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "glean-build"
3-
version = "18.0.2"
3+
version = "18.0.6"
44
edition = "2021"
55
description = "Glean SDK Rust build helper"
66
repository = "https://github.com/mozilla/glean"

glean-core/build/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use std::{env, path::PathBuf};
3939

4040
use xshell_venv::{Result, Shell, VirtualEnv};
4141

42-
const GLEAN_PARSER_VERSION: &str = "18.0.2";
42+
const GLEAN_PARSER_VERSION: &str = "18.0.6";
4343

4444
/// A Glean Rust bindings generator.
4545
pub struct Builder {

glean-core/ios/Glean/Metrics/ObjectMetric.swift

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,11 @@
55
/// An object that can be serialized into JSON.
66
///
77
/// Objects are defined by their structure in the metrics definition.
8-
public protocol ObjectSerialize: Decodable {
8+
public protocol ObjectSerialize: Codable {
99
func intoSerializedObject() -> String
1010
}
1111

12-
extension Array: ObjectSerialize where Element: ObjectSerialize {
13-
public func intoSerializedObject() -> String {
14-
var json = "["
15-
var first = true
16-
for elem in self {
17-
if !first {
18-
json.append(",")
19-
}
20-
first = false
21-
json.append(elem.intoSerializedObject())
22-
}
23-
json.append("]")
24-
return json
25-
}
26-
}
27-
28-
extension String: ObjectSerialize {
12+
extension Array: ObjectSerialize where Element: Codable {
2913
public func intoSerializedObject() -> String {
3014
let jsonEncoder = JSONEncoder()
3115
let jsonData = try! jsonEncoder.encode(self)
@@ -34,18 +18,6 @@ extension String: ObjectSerialize {
3418
}
3519
}
3620

37-
extension Bool: ObjectSerialize {
38-
public func intoSerializedObject() -> String {
39-
return self ? "true" : "false"
40-
}
41-
}
42-
43-
extension Int64: ObjectSerialize {
44-
public func intoSerializedObject() -> String {
45-
return String(self)
46-
}
47-
}
48-
4921
/// This implements the developer facing API for the object metric type.
5022
///
5123
/// Instances of this class type are automatically generated by the parsers at built time,

glean-core/ios/GleanTests/Metrics/ObjectMetricTests.swift

Lines changed: 117 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,82 @@
55
@testable import Glean
66
import XCTest
77

8-
struct BalloonsObjectItem: Decodable, Equatable, ObjectSerialize {
8+
struct BalloonsObjectItem: Codable, Equatable {
99
var colour: String?
1010
var diameter: Int64?
11+
var anotherValue: Bool?
1112

12-
func intoSerializedObject() -> String {
13-
var data: [String] = []
14-
if let val = self.colour {
15-
var elem = "\"colour\":"
16-
elem.append(val.intoSerializedObject())
17-
data.append(elem)
13+
enum CodingKeys: String, CodingKey {
14+
case colour = "colour"
15+
case diameter = "diameter"
16+
case anotherValue = "another_value"
17+
}
18+
19+
func encode(to encoder: Encoder) throws {
20+
var container = encoder.container(keyedBy: CodingKeys.self)
21+
if let colour = self.colour {
22+
try container.encode(colour, forKey: .colour)
1823
}
19-
if let val = self.diameter {
20-
var elem = "\"diameter\":"
21-
elem.append(val.intoSerializedObject())
22-
data.append(elem)
24+
if let diameter = self.diameter {
25+
try container.encode(diameter, forKey: .diameter)
26+
}
27+
if let anotherValue = self.anotherValue {
28+
try container.encode(anotherValue, forKey: .anotherValue)
2329
}
24-
let obj = data.joined(separator: ",")
25-
let json = "{" + obj + "}"
26-
return json
2730
}
2831
}
29-
3032
typealias BalloonsObject = [BalloonsObjectItem]
3133

34+
// generated from
35+
//
36+
// ```
37+
// structure:
38+
// type: object
39+
// properties:
40+
// key1:
41+
// type: string
42+
// another_value:
43+
// type: number
44+
// sub_array:
45+
// type: array
46+
// items:
47+
// type: number
48+
// ```
49+
struct ToplevelObjectObject: Codable, Equatable, ObjectSerialize {
50+
var key1: String?
51+
var anotherValue: Int64?
52+
var subArray: ToplevelObjectObjectSubArray = []
53+
54+
enum CodingKeys: String, CodingKey {
55+
case key1 = "key1"
56+
case anotherValue = "another_value"
57+
case subArray = "sub_array"
58+
}
59+
60+
func encode(to encoder: Encoder) throws {
61+
var container = encoder.container(keyedBy: CodingKeys.self)
62+
if let key1 = self.key1 {
63+
try container.encode(key1, forKey: .key1)
64+
}
65+
if let anotherValue = self.anotherValue {
66+
try container.encode(anotherValue, forKey: .anotherValue)
67+
}
68+
if subArray.count > 0 {
69+
let subArray = self.subArray
70+
try container.encode(subArray, forKey: .subArray)
71+
}
72+
}
73+
74+
func intoSerializedObject() -> String {
75+
let jsonEncoder = JSONEncoder()
76+
let jsonData = try! jsonEncoder.encode(self)
77+
let json = String(data: jsonData, encoding: String.Encoding.utf8)!
78+
return json
79+
}
80+
}
81+
typealias ToplevelObjectObjectSubArray = [ToplevelObjectObjectSubArrayItem]
82+
typealias ToplevelObjectObjectSubArrayItem = Int64
83+
3284
class ObjectMetricTypeTests: XCTestCase {
3385
override func setUp() {
3486
resetGleanDiscardingInitialPings(testCase: self, tag: "ObjectMetricTypeTests")
@@ -132,4 +184,54 @@ class ObjectMetricTypeTests: XCTestCase {
132184
XCTAssertEqual(2, snapshot.count)
133185
XCTAssertEqual(expected, snapshot)
134186
}
187+
188+
func testObjectDecodesFromSnakeCase() {
189+
let metric = ObjectMetricType<BalloonsObject>(CommonMetricData(
190+
category: "test",
191+
name: "balloon",
192+
sendInPings: ["store1"],
193+
lifetime: .ping,
194+
disabled: false
195+
))
196+
197+
XCTAssertNil(metric.testGetValue())
198+
199+
var balloons: BalloonsObject = []
200+
balloons.append(BalloonsObjectItem(colour: "red", diameter: 5, anotherValue: true))
201+
balloons.append(BalloonsObjectItem(colour: "green", anotherValue: false))
202+
metric.set(balloons)
203+
204+
let snapshot = metric.testGetValue()!
205+
XCTAssertNotNil(snapshot)
206+
XCTAssertEqual(2, snapshot.count)
207+
208+
XCTAssertEqual(snapshot[0].colour, "red")
209+
XCTAssertEqual(snapshot[0].diameter, 5)
210+
XCTAssertEqual(snapshot[0].anotherValue, true)
211+
XCTAssertEqual(snapshot[1].colour, "green")
212+
XCTAssertNil(snapshot[1].diameter)
213+
XCTAssertEqual(snapshot[1].anotherValue, false)
214+
}
215+
216+
func testObjectWithStructureOnToplevel() {
217+
let metric = ObjectMetricType<ToplevelObjectObject>(CommonMetricData(
218+
category: "test",
219+
name: "toplevel_object",
220+
sendInPings: ["store1"],
221+
lifetime: .ping,
222+
disabled: false
223+
))
224+
225+
XCTAssertNil(metric.testGetValue())
226+
227+
let obj = ToplevelObjectObject(key1: "test", anotherValue: 3, subArray: [1, 2, 3])
228+
metric.set(obj)
229+
230+
let snapshot = metric.testGetValue()!
231+
XCTAssertNotNil(snapshot)
232+
233+
XCTAssertEqual("test", snapshot.key1)
234+
XCTAssertEqual(3, snapshot.anotherValue)
235+
XCTAssertEqual([1, 2, 3], snapshot.subArray)
236+
}
135237
}

0 commit comments

Comments
 (0)