Upgrade to Pro — share decks privately, control downloads, hide ads and more …

waiwai-swiftpm-part2

d_date
February 07, 2022

 waiwai-swiftpm-part2

d_date

February 07, 2022
Tweet

More Decks by d_date

Other Decks in Technology

Transcript

  1. SE-0303 SE-0325 Build Tool Plugins લճͷ͓͞Β͍ • Ϗϧυதʹ࣮ߦ͢ΔπʔϧΛϓϥάΠϯͱͯ͠ఆٛͰ͖Δɻ
 e.g.) ίʔυੜ੒

    • Swift package / Xcode྆ํͰαϙʔτ͞Ε͍ͯΔ • App SandboxͷΈΞΫηεΛڐ༰ɻNetwork Access΋Ͱ͖ͳ͍ɻ https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
  2. Examples SwiftGen - Plugin // swift-tools-version: 5.6 import PackageDescription let

    package = Package( name: "SwiftGen", targets: [ .plugin( name: "SwiftGenPlugin", capability: .buildTool(), dependencies: ["SwiftGen"] ), .binaryTarget( name: "SwiftGen", url: "https://url/to/the/built/swiftgen-executables.zip", checksum: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ), ] ) SwiftGen ᵓ Package.swift ᵓ Plugins │ └ SwiftGenPlugin │ └ plugin.swift └ Sources └ SwiftGen └ ...
  3. SE-0305 Artifact archive bundle લճͷ͓͞Β͍ • Swift ੡Ͱ͸ͳ͍ CLI πʔϧ͸ࣄલʹϏϧυ͓ͯ͘͠ඞཁ͕͋Δ

    • Target.binaryTargetͰ artifactbundle ܗࣜΛαϙʔτͯ͠ɺTarget triple͝ͱʹexecutableΛ഑ஔɾμ΢ϯϩʔυͰ͖ΔΑ͏ʹ͢Δ <name>.artifactbundle ᵓ info.json ᵓ <artifact> │ ᵓ <variant> │ │ ᵓ <executable> │ │ └ <other fi les> │ └ <variant> │ ᵓ <executable> │ └ <other fi les> ᵓ <artifact> │ └ <variant> │ ᵓ <executable> │ └ <other fi les> │ <artifact> ᴽ └ᴻ
  4. SE-0332 Command Plugins લճͷ͓͞Β͍ • Tool version 5.6Ҏ߱Ͱɺcommand λΠϓͷ Package

    pluginΛهࡌͰ͖ΔΑ͏ʹͳ Γɺswift package subcommand Λར༻ͯ͠ݺͼग़ͤΔΑ͏ʹͳͬͨɻ • Prede fi ned: generateDocumentation, codeFormat • Custom: (Build Artifactͷ࡞੒ͳͲ) • Package manager΁ͷproxyΛ࢖ͬͯBuild / Test / Symbol graphͷऔಘ͕Ͱ͖Δ • ඞཁʹԠͯ͡ϢʔβʔʹڐՄΛٻΊΔ • writeToPackageDirectory https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
  5. #3649 Enable lenient parsing of Git version tags • ηϚϯςΟοΫόʔδϣϯʹ͓͍ͯɺMajor

    ͱ Miner͚ͩΛؚΉ Git tag ʹର͠ ͯґଘؔ܎ΛղܾͰ͖ΔΑ͏ʹͳͬͨɻ
 X.Y ͱ͍͏ tag ͸ X.Y.0 ͱͯ͠ѻΘΕɺطଘͷϦϙδτϦͷޓ׵ੑ͕վળ͞Ε Δɻ https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
  6. #3686 Correct semantic version parsing and comparison • ηϚϯςΟοΫόʔδϣϯʹ͓͚Δߏจղੳͱൺֱ͕ SemVer

    2.0.0ʹݫີʹश͏Α͏ʹͳͬͨɻ
 ઌߦ͢Δ + ͕ͳ͍৔߹ͷΈɺ- ΛVersion coreͱpre-release identi fi erͷ۠੾Γจࣈ (delimiter) ͱ͠ ͯѻ͏Α͏ʹͳͬͨɻͦΕҎ֎ͷ৔߹͸ɺBuild metadata identi fi er ͷҰ෦ͱͯ͠ѻ͏Α͏ʹͳͬ ͨ
 
 ྫ) 1.2.3+some-meta.data
 ͍··Ͱ͸ɺ1.2.3+some Λ Version core, meta.data Λpre-release identi fi erͱ͍͕ͯͨ͠ɺ
 1.2.3 Λ Version core, some-meta.data Λ Build metadata ͱͯ͠औΓѻΘΕΔΑ͏ʹͳͬͨ • ൺֱʹ͍ͭͯ͸ɺBuild metadataΛແࢹͯ͠ɺMajor, Minor, Patch, Pre-release identi fi er ͕Ұக͠ ͨ࣌ͷΈ౳͍͠΋ͷͱͯ͠ѻ͏ https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
  7. #3641 Deprecate name attribute on package dependencies • .package(name:, url:)͕ඇਪ঑ͱͳΓɺ.package(url:)Λར༻͢ΔΑ͏ʹਪ঑

    ͞ΕΔΑ͏ʹͳͬͨɻ 
 Swift 5.5 ͰnameΛ໌ࣔతʹࢦఆ͠ͳͯ͘΋Α͘ͳͬͨͨΊ
 ※soft deprecated ͱͳ͍ͬͯΔ͕ɺݴޠ࢓্༷ deprecated ͸ deprecated • .package(url: String, exact: Version) ͕௥Ճ • ґଘཁ݅ͷ enum calling convention ͕ඇਪ঑ͱͳΓɺϥϕϧ෇͖Ҿ਺ͱͳΔ ◦.package(url: String, .branch(String)) -> .package(url: String, branch: String) ◦.package(url: String, .revision(String)) -> .package(url: String, revision: String) ◦.package(url: String, .exact(Version)) -> .package(url: String, exact: Version) https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
  8. #3717 Update the resolved file format Package.resolved ͕ V2 ΁

    https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56 { "pins": [ { "identity": "abseil-cpp-swiftpm", "kind": "remoteSourceControl", "location": "https://github.com/firebase/abseil-cpp-SwiftPM.git", "state": { "revision": "fffc3c2729be5747390ad02d5100291a0d9ad26a", "version": "0.20200225.4" } }, { "identity": "aexml", "kind": "remoteSourceControl", "location": "https://github.com/tadija/AEXML", "state": { "revision": "38f7d00b23ecd891e1ee656fa6aeebd6ba04ecc3", "version": "4.6.1" } }, ], "version": 2 } { "object": { "pins": [ { "package": "abseil", "repositoryURL": "https://github.com/firebase/abseil-cpp-SwiftPM.git", "state": { "branch": null, "revision": "fffc3c2729be5747390ad02d5100291a0d9ad26a", "version": "0.20200225.4" } }, { "package": "AEXML", "repositoryURL": "https://github.com/tadija/AEXML", "state": { "branch": null, "revision": "38f7d00b23ecd891e1ee656fa6aeebd6ba04ecc3", "version": "4.6.1" } } ] }, "version": 1 }
  9. #3809 Implement TOFU for package downloads Trust-on- fi rst-use (

    TOFU 📛 )Ͱ Package ͷηΩϡϦςΟڧԽ • PackageͷηΩϡϦςΟڧԽͷͨΊʹɺSwiftPM͸ trust-on- fi rst-use ( TOFU ) validationΛߦ͏ɻ • Package ͕ Git repository / Package registry͔Β࠷ॳʹμ΢ϯϩʔυ͞Εͨͱ͖ ʹɺPackage ͷ fi ngerprint ͕ه࿥͞ΕΔΑ͏ʹͳͬͨɻ • Package Registryͷ৔߹͸ɺsource archive checksum • Source controlͷ৔߹͸ɺGit revision • ޙଓͷμ΢ϯϩʔυʹ͸ɺҎલه࿥͞Εͨ஋ͱҰக͢Δ fi nger pin͕ඞཁɻ https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
  10. #3670, #3901, #3942 Config file location changing Package.resolved ͕ V2

    ΁ • SE-0292 (Package registry)ͳͲʹΑͬͯɺcon fi gurationσΟϨΫτϦʹΑΓݎ ࿚ͳσΟϨΫτϦߏ଄͕ٻΊΒΕΔΑ͏ʹͳͬͨɻ • <project>/.swiftpm/con fi g (mirrors fi le) -> <project>/.swiftpm/con fi guration/mirrors.json • ~/.swiftpm/con fi g/collections.json (collection fi le) -> ~/.swiftpm/con fi guration/collections.json • Swift 5.6͕ࣗಈͰίϐʔͯ͠ɺϢʔβʔʹݹ͍΋ͷΛফ͢Α͏ʹwarningΛग़͢ https://github.com/apple/swift-package-manager/blob/main/CHANGELOG.md#swift-56
  11. Additional Package APIs • SE-0303ͷ TargetBuildContext Λ PluginContext ͱͯ͠Package graphશମͷ৘ใ

    ΛؚΉΑ͏ʹҰൠԽ͢Δɻ • PluginContextʹ͸Packageͷࢀর͕ఏڙ͞ΕΔͷͰɺϓϥάΠϯͷεΫϦϓτͰґ ଘ͢ΔαϒάϥϑʹΞΫηεͰ͖Δɻˠ Command Plugin • ༗޲ඇ८ճάϥϑ(DAG)Ͱ͋Δґଘؔ܎ΛτϙϩδΧϧιʔτ͢ΔΑ͏ͳAPI΋ఏڙ • ͦΕͧΕͷDependency TargetͷSearch PathΛؚΉίϚϯυϥΠϯҾ਺Λੜ੒ ͢ΔΑ͏ͳχʔζʹରԠ͢Δ
  12. /// Represents a single product defined in a package. public

    protocol Product { /// Unique identifier for the product. var id: ID { get } typealias ID = String /// The name of the product, as defined in the package manifest. This name /// is unique among the products of the package in which it is defined. var name: String { get } /// The targets that directly comprise the product, in the order in which /// they are declared in the package manifest. The product will contain the /// transitive closure of the these targets and their dependencies. Some /// kinds of products have further restrictions on the set of targets (for /// example, an executable product must have one and only one target that /// defines the main entry point for an executable). var targets: [Target] { get } }
  13. /// Represents a single target defined in a package. public

    protocol Target { /// Unique identifier for the target. var id: ID { get } typealias ID = String /// The name of the target, as defined in the package manifest. This name /// is unique among the targets of the package in which it is defined. var name: String { get } /// The absolute path of the target directory in the local file system. var directory: Path { get } /// Any other targets on which this target depends, in the same order as /// they are specified in the package manifest. Conditional dependencies /// that do not apply have already been filtered out. var dependencies: [TargetDependency] { get } } /// Represents a dependency of a target on a product or on another target. public enum TargetDependency { /// A dependency on a target in the same package. case target(Target) /// A dependency on a product in another package. case product(Product) }
  14. extension Target { /// The transitive closure of all the

    targets on which the reciver depends, /// ordered such that every dependency appears before any other target that /// depends on it (i.e. in "topological sort order"). public var recursiveTargetDependencies: [Target] { // FIXME: We can rewrite this to use a stack instead of recursion. var result = [Target]() var visited = Set<Target.ID>() func visit(target: Target) { guard !visited.insert(target.id).inserted else { return } target.dependencies.forEach{ visit(dependency: $0) } result.append(target) } func visit(dependency: TargetDependency) { switch dependency { case .target(let target): visit(target: target) case .product(let product): product.targets.forEach{ visit(target: $0) } } } return result } } https://github.com/apple/swift-package-manager/pull/3758/ fi les#di ff -79b44ed51fc53000c5d9cfd941b77065d03a99760a8b1ddd6cf5fafdc5f5835fR417-R440
  15. SE-0292 Package Registry Service Accepted • DependencyͷdownloadʹιʔεϦϙδτϦͷURLΛࢦఆͯ͠gitΛ࢖͏ͷ͸ద͍ͯ͠ͳ͍ • ࠶ݱੑ: όʔδϣϯλά͸͍ͭͰ΋ผίϛοτʹׂΓ౰ͯՄೳͳͷͰɺϏϧυ͞ΕͨλΠϛϯάʹΑͬͯҟͳΔ

    Ϗϧυ੒Ռ෺ʹͳΔՄೳੑ͕͋Δ • Մ༻ੑ: ϦϙδτϦ͸Ҡಈͨ͠Γ࡟আ͞ΕͨΓ͢Δ • ޮ཰: ύοέʔδͷ͢΂ͯͷόʔδϣϯ͕μ΢ϯϩʔυ͞Εͯ͠·͏ • ଎౓: history͕େ͖͍ͱ஗͘ͳΔɻΫϩʔϯ͸αʔόʔʹ΋ΫϥΠΞϯτʹ΋ίετɻ • Package registry: RubyGems / PyPl / npm / crates.io • SwiftPMͷpackage registry͸gitΑΓ΋ߴ଎Ͱ৴པੑͷߴ͍ґଘؔ܎ղܾ͕๬ΊΔɻ • Package search, Security audit, local o ff l ine cache
  16. Package registry service Method Path Description GET /{scope}/{name} List package

    releases GET /{scope}/{name}/{version} Fetch metadata for a package release GET /{scope}/{name}/{version}/Package.swift{?swift-version} Fetch manifest for a package release GET /{scope}/{name}/{version}.zip Download source archive for a package release GET /identi fi ers{?url} Lookup package identi fi ers registered for a URL
  17. Changes to Swift Package Manager Package Identity • ݱࡏpackage ID͸URLͷlast

    path components • scope.package-name ʹมߋ͢Δ • scope͸namespaceͰ࠷େ39จࣈ • package-name͸scope಺ͷϢχʔΫͳ໊લͰ࠷େ100จࣈ
  18. Changes to Swift Package Manager Dependency graph resolution • PackageContainerΛpackage

    resolutionͷtop-level unitͱ͢Δ • RegistryPackageContainer͕HTTPϦ ΫΤετͱಉ౳ͷૢ࡞Λߦ͏ public protocol PackageContainer { /// The identifier for the package. var package: PackageReference { get } func isToolsVersionCompatible(at version: Version) -> Bool func toolsVersion(for version: Version) throws -> ToolsVersion /// Get the list of versions which are available for the package. /// /// The list will be returned in sorted order, with the latest version *first*. /// All versions will not be requested at once. Resolver will request the next one only /// if the previous one did not satisfy all constraints. func toolsVersionsAppropriateVersionsDescending() throws -> [Version] /// Get the list of versions in the repository sorted in the ascending order, that is the earliest /// version appears first. func versionsAscending() throws -> [Version] func versionsDescending() throws -> [Version] // FIXME: We should perhaps define some particularly useful error codes // here, so the resolver can handle errors more meaningfully. // /// Fetch the declared dependencies for a particular version. /// /// This property is expected to be efficient to access, and cached by the /// client if necessary. /// /// - Precondition: `versions.contains(version)` /// - Throws: If the version could not be resolved; this will abort /// dependency resolution completely. func getDependencies(at version: Version, productFilter: ProductFilter) throws -> [PackageContainerConstraint] /// Fetch the declared dependencies for a particular revision. /// /// This property is expected to be efficient to access, and cached by the /// client if necessary. /// /// - Throws: If the revision could not be resolved; this will abort /// dependency resolution completely. func getDependencies(at revision: String, productFilter: ProductFilter) throws -> [PackageContainerConstraint] /// Fetch the dependencies of an unversioned package container. /// /// NOTE: This method should not be called on a versioned container. func getUnversionedDependencies(productFilter: ProductFilter) throws -> [PackageContainerConstraint] /// Get the updated identifier at a bound version. /// /// This can be used by the containers to fill in the missing information that is obtained /// after the container is available. The updated identifier is returned in result of the /// dependency resolution. func loadPackageReference(at boundVersion: BoundVersion) throws -> PackageReference }
  19. Changes to Swift Package Manager Tasks performed by Swift Package

    Manager during dependency resolution Task Git operation Registry request Fetch the contents of a package git clone && git checkout GET /{scope}/{name}/{version}.zip List the available tags for a package git tag GET /{scope}/{name} Fetch a package manifest git clone GET /{scope}/{name}/{version}/Package.swift
  20. Appendix: HTTPClient in SwiftPM • Apple/swift-package-managerͷSources/Basics/HTTPClient • ඪ४తͳHTTPClientͷ࣮૷ͱͯ͠Α͍͔΋ • ͦͷଞSwiftPM΍llbuildͷcommon

    infrastructure ͱͯ͠ apple/swift-tools-support-core ͱ͍͏ͷ΋͋Δ • https://github.com/apple/swift-tools-support-core
  21. Changes to Package.resolved • Swift Package Registry΁ͷϦϦʔε͸ZipϑΝΠϧͱͯ͠ΞʔΧΠϒ͞ΕΔɻ • ֎෦ύοέʔδͷґଘؔ܎͕RegistryΛհͯ͠μ΢ϯϩʔυ͞ΕΔͱɺPackage.resolvedͷchecksum ͱɺswift

    package compute-checksumίϚϯυͷchecksumͱൺֱ͢ΔɻPackage.resolvedʹͳ͚Ε͹ ௥هɻ $ swift package compute-checksum LinkedList-1.2.0.zip 1feec3d8d144814e99e694cd1d785928878d8d6892c4e59d12569e179252c535 { "object": { "pins": [ { "package": "mona.LinkedList", "state": { "checksum": "ed008d5af44c1d0ea0e3668033cae9b695235f18b1a99240b7cf0f3d9559a30d", "version": "1.2.0" } } ] }, "version": 1 }
  22. Changes to Package.resolved • Checksum͕ҟͳ͍ͬͯΕ͹ɺμ΢ϯϩʔυΛڋ൱͢Δɻ $ swift build error: checksum

    of downloaded source archive of dependency 'mona.LinkedList' (c2b934fe66e55747d912f1cfd03150883c4f037370c40ca2ad4203805db79457) does not match checksum speci fi ed by the manifest (ed008d5af44c1d0ea0e3668033cae9b695235f18b1a99240b7cf0f3d9559a30d)
  23. Archive-source subcommand • ଞͷPackage ManagerͷࣄྫΛݟΔͱɺChecksumͷෆҰக͸ɺِ଄΍ഁଛΑΓ΋ɺArchiveͷ࡞੒΍ɺ ChecksumͷෆҰக͕ݪҼͷ͜ͱͷํ͕ଟ͍ • swift package archive-source

    ίϚϯυ͸ඪ४ͷsource archiveΛ࡞੒͢Δํ๏Λఏڙ͢Δ SYNOPSIS swift package archive-source [--output=< fi le>] OPTIONS -o < fi le>, --output=< fi le> Write the archive to < fi le>. If unspeci fi ed, the package is written to `\(PackageName).zip`.
  24. Archive-source subcommand • ίϚϯυΛrootͰ࣮ߦ͢ΔͱɺݱࡏͷWorking treeͷsource archiveΛ࡞੒͢Δ $ tree -a -L

    1 LinkedList ᵓ── .git ᵓ── Package.swift ᵓ── README.md ᵓ── Sources └── Tests $ head -n 5 Package.swift // swift-tools-version:5.3 import PackageDescription let package = Package( name: "LinkedList", $ swift package archive-source Created LinkedList.zip
  25. Archive-source subcommand • σϑΥϧτͰ͸ɺ<Package name>.zip ʹͳΔɻ- - outputͰมߋՄೳ • Archive-source

    ͸git-archive ʹzip formatΛࢦఆ͠ɺdefault compression levelΛࢦఆͨ͠΋ͷͱಉ౳ɻ
 Note: export-ignoreଐੑͷϑΝΠϧ͸ແࢹ͞ΕΔɻ.git΍.buildͷΑ͏ͳӅ͠ϑΝΠϧ / σΟϨΫτϦ΋ؚ Ήɻ $ git checkout 1.2.0 $ swift package archive-source --output="LinkedList-1.2.0.zip" # Created LinkedList-1.2.0.zip $ git archive --format zip \ --pre fi x LinkedList-1.2.0 --output LinkedList-1.2.0.zip \ 1.2.0
  26. Registry configuration subcommands swift package-registry set • GitHubͷΑ͏ͳPublic RegistryҎ֎ʹCustom RegistryΛߏ੒͢ΔαϒίϚϯυ

    • ηϧϑϗετ͍ͨ͠Private Package͕͋Δ • ϛϥʔαΠτΛཱ͍ͯͨ৔߹ • ঝೝ͢ΈύοέʔδͷΈΛར༻ͤ͞ΔϙϦγʔΛద༻ͤ͞Δ৔߹ • ύοέʔδͷར༻ঢ়گͷޮՌଌఆΛߦ͍ɺϥϯΩϯά΍ϥΠηϯεྉۚΛ੥ٻ͢Δ৔߹ SYNOPSIS swift package-registry set <url> [options] OPTIONS: --global Apply settings to all projects for this user --scope Associate the registry with a given scope --login Specify a user name for the remote machine --password Supply a password for the remote machine
  27. Registry configuration subcommands swift package-registry set • PackageͷRootͰ࣮ߦ͢Δͱɺ.swiftpm/con fi guration/registries.json

    ϑΝΠϧ͕࡞੒͞ΕΔ • είʔϓ͕ࢦఆ͞Ε͍ͯͳ͍৔߹͸ [default] ʹͳΔɻ • ྫ͑͹ɺ֎෦΁ͷωοτϫʔΫ઀ಠΛڐՄ͠ͳ͍ϏϧυαʔόʔͰ͸ɺInternal registry service Λར༻ ͯ͠ґଘؔ܎Λղܾ͢ΔΑ͏ʹRegistry URLΛߏ੒͢Δ $ swift package-registry set https://internal.example.com/ { "registries": { "[default]": { "url": "https://internal.example.com" } }, "version": 1 }
  28. Registry configuration subcommands Associating a registry with a scope •

    scopeΦϓγϣϯΛ͚ͭͯPackageͷscopeΛࢦఆ͢ΔͱɺΧελϜϨδε τϦʹؔ࿈෇͚͢Δ͜ͱ͕Ͱ͖Δɻ • ΧελϜϨδετϦ͕Package scopeͱؔ࿈෇͚͞Ε͍ͯΔͱɺͦͷείʔ ϓͱͷύοέʔδͷґଘؔ܎͸ɺఏڙ͞ΕͨURLΛհͯ͠ղܾ͞ΕΔɻ
 ྫ) 
 example.Foo → Package Registryͷexample scopeΛར༻
 Foo → git URLΛར༻
 $ swift package-registry set https://internal.example.com/ - -scope example { "registries": { "example": { "url": "https://internal.example.com" } }, "version": 1 }
  29. Registry configuration subcommands Unsetting a custom registry • ΧελϜϨδετϦΛղআ͢Δ SYNOPSIS

    swift package-registry unset [options] OPTIONS: --global Apply settings to all projects for this user --scope Removes the registry's association to a given scope
  30. Registry configuration subcommands Global registry con fi guration • GlobalΦϓγϣϯΛ͚ͭΔͱɺ~/.swiftpm/con

    fi guration/registries.json Λߋ৽͢Δ • Local Con fi guration ͸ GlobalΑΓ༏ઌ͞ΕΔ
 ྫ) foo scope͸ https://local.example.com Λར༻͢Δ • ΧϨϯτσΟϨΫτϦͷPackageϚχϑΣετ (./Package.swift) • طଘͷlock fi le (./Package.resolved) • Local con fi guration (./.swiftpm/con fi guration/registries.json) • Global con fi guration (~/.swiftpm/con fi guration/registries.json) SYNOPSIS swift package-registry unset [options] OPTIONS: --global Apply settings to all projects for this user --scope Removes the registry's association to a given scope // Global configuration (~/.swiftpm/configuration/registries.json) { "registries": { "[default]": { "url": "https://global.example.com" }, "foo": { "url": "https://global.example.com" }, }, "version": 1 } // Local configuration (.swiftpm/configuration/registries.json) { "registries": { "foo": { "url": "https://local.example.com" } }, "version": 1 }
  31. Registry configuration subcommands Credential • - - login / -

    -password ΦϓγϣϯΛ౉͢ͱɺΫϨσϯγϟϧΛఏڙͰ͖Δ • login ΩʔΛؚΉ registries.json ͷରԠ͢ΔΦϒδΣΫτʹ౉͞Εͨ஋Λ࣋ͭΩʔ͕௥Ճ͞ΕΔɻ • .netrcϑΝΠϧʹಛఆͷϚγϯͱϩάΠϯͷطଘͷΤϯτϦ͕͋Ε͹ɺpassword͕ߋ৽͞ΕΔɻ $ swift package-registry set https://internal.example.com/ \ --login jappleseed --password alpine $ cat .netrc machine internal.example.com login jappleseed password alpine { "registries": { "[default]": { "url": "https://internal.example.com" "login": "jappleseed" } }, "version": 1 }
  32. Changes to config subcommand Set-mirror option for package identi fi

    ers • ݱࡏઃఆͰ͖Δset-mirrorίϚϯυʹ —original-urlΛஔ͖׵͑—package-identi fi erΦϓγϣϯΛ௥Ճ • .swiftpm/con fi guration/mirrors.json ϑΝΠϧΛੜ੒͢Δ $ swift package con fi g set-mirror \ --original-url https:///github.com/mona/linkedlist \ --mirror-url https:///github.com/octocorp/swiftlinkedlist { "object": [ { "mirror": "https://github.com/OctoCorp/ SwiftLinkedList.git", "original": "mona.LinkedList" } ], "version": 1 }
  33. Package Registry Service Publish Point • swift package archive-source ͰzipϑΝΠϧΛ࡞੒͢Δɻ

    • ࣍ͷϦΫΤετΛߦͳͬͯɺϦϦʔεΛΞοϓϩʔυ͢Δ • ϨδετϦ͕ϦΫΤετʹԠ౴͠ɺόʔδϣϯΛར༻Մೳʹͨ͠ΒɺGETͰऔಘͰ͖Δ $ curl -X PUT --netrc \ -H "Accept: application/vnd.swift.registry.v1+json" \ -F source-archive="@LinkedList-1.1.1.zip" \ "https://registry.example.com/mona/LinkedList?version=1.1.1"
  34. Security • ֎෦ʹґଘؔ܎͕͋Ε͹߈ܸର৅ྖҬ͕૿Ճ͢Δ͕ɺϦεΫ͸ܰݮͰ͖ɺGitΛ࢖͏ΑΓ΋҆શͰηΩϡϦςΟ͕อ ূͰ͖Δ • Package scopeͷจࣈηοτ͸ݶఆ͞Ε͓ͯΓɺϗϞάϥϑ߈ܸΛ๷͙ • ಉ͡จࣈʹݟ͑ͯҧ͏จࣈίʔυͷจࣈΛར༻ِͯ͠ͷURLʹ༠ಋ͢Δख๏ •

    ઌ಄ɺ຤ඌɺ࿈ଓͷϋΠϑϯΛېࢭɻΞϯμʔείΞ͸׬શʹېࢭɻ • .ͷېࢭɻείʔϓͷυϝΠϯόϦΞϯτͱͷޡղΛ๷͙ʢapple.com͸ແޮɻappleͱࠞಉͰ͖ͳ͍ʣ • ύοέʔδ͸είʔϓ಺ʹొ࿥͞ΕɺλΠϙεΫϫοτΛܰݮ͢ΔɻޡղΛট͘Α͏ͳείʔϓͷׂΓ౰ͯΛ੍ ݶ͢ΔʢG00gleͳͲʣ • ۟ಡ఺΍ۭനจࣈ͸ΫϩεαΠτεΫϦϓςΟϯά΍ɺCRLFΠϯδΣΫγϣϯΛট͘ͷͰېࢭɻ
  35. STRIDE • ͜ͷϓϩϙʔβϧʹ͓͚ΔηΩϡϦςΟͷӨڹͷཧղͷͨΊʹɺSTRIDEχʔϞχοΫΛར༻͢Δɻ ڴҖ ৵֐͢ΔγεςϜಛੑ Spoo fi ng (ͳΓ͢·͠) Authenticity

    (ਅਖ਼ੑ) Tampering (վ͟Μʣ Integrity (׬શੑ) Repudiation (൱ೝ) Non-repudiation (൱ೝ๷ࢭʣ Information disclosure (৘ใ࿙Ӯʣ Con fi dentiality (ػີੑ) Denial of serviceʢαʔϏεڋ൱ʣ Availability (Մ༻ੑ) Elevation of privilegeʢಛݖͷঢ֨ʣ Authorization (ೝՄ)
  36. STRIDE Spoo fi ngʢͳΓ͢·͠ʣ • ߈ܸऀ͸ɺΫϥΠΞϯτͱύοέʔδϨδετϦͷؒʹϓϩΩγΛૠೖͯ͠ɺͦͷϗετͷࢿ֨৘ใΛ๣ड͠ɺͦΕΒΛ ࢖༻ͯ͠ޙଓͷཁٻͰϢʔβʔʹͳΓ͢·͢Մೳੑ͕͋Γ·͢ɻ • ͜ΕΒͷࢿ֨৘ใʹؔ࿈෇͚ΒΕ͍ͯΔಛݖͷൣғͱϨϕϧʹΑͬͯ͸ɺ͜ͷ߈ܸͷӨڹ͕େ͖͘ͳΔՄೳੑ͕͋Γ· ͢ɻͨͩ͠ɺHTTPSΛհͨ҆͠શͳ઀ଓͷ࢖༻͸ɺશମతͳϦεΫΛܰݮ͢Δͷʹେ͍ʹ໾ཱͪ·͢ɻ

    • Swift Package Manager͸ɺ࣍ͷରࡦΛߨ͡Δ͜ͱͰɺ͜ͷϦεΫΛ͞ΒʹܰݮͰ͖·͢ɻ • ͢΂ͯͷURLʹHTTPSΛద༻͢Δ • DNS over HTTPSʢDoHʣΛ࢖༻ͨ͠URLͷղܾ • Punycodeͱͯ͠ද͞ΕΔࠃࡍԽυϝΠϯ໊ʢIDNʣͷURLΛཁٻ͢Δ • Publish͢Δࡍ͸ϦΫΤετʹଟཁૉೝূΛར༻͢Δ͜ͱΛਪ঑͢Δ
  37. STRIDE Tampering (վ͟Μ) • ߈ܸऀ͸ɺΫϥΠΞϯτͱύοέʔδϨδετϦͷؒʹϓϩΩγΛૠೖͯ͠ɺѱҙͷ͋ΔίʔυΛؚΉ ZipϑΝΠϧΛ࡞੒ͯ͠ૹ৴͢ΔՄೳੑ͕͋Γ·͢ɻ • ͜ͷΑ͏ͳ߈ܸͷӨڹ͸જࡏతʹߴ͘ͳΓ·͕͢ɺμ΢ϯϩʔυ͞ΕͨιʔεΞʔΧΠϒͷ੔߹ੑΛݕ ূ͢ΔͨΊʹ҉߸ԽνΣοΫαϜΛ࢖༻͢Δ͜ͱͰɺϦεΫ͸େ෯ʹܰݮ͞Ε·͢ɻ •

    ੔߹ੑνΣοΫ͚ͩͰ͸ɺύοέʔδِ͕଄Ͱ͸ͳ͍͜ͱΛอূͰ͖·ͤΜɻ߈ܸऀ͸ϗετͷWebα ΠτΛةݥʹ͞Β͠ɺѱҙͷ͋Δύοέʔδʹ༗ޮͳνΣοΫαϜΛఏڙ͢ΔՄೳੑ͕͋Γ·͢ɻ $ echo "$(swift package compute-checksum LinkedList-1.2.0.zip) *LinkedList-1.2.0.zip" | \ shasum -a 256 -c - LinkedList-1.2.0.zip: OK
  38. STRIDE Tampering (վ͟Μ) ʹର͢ΔTOFUϞσϧ • Package.resolvedʹTrust on First UseʢTOFUʣηΩϡϦςΟϞσϧΛఏڙ͠·͢ɻ͜ΕʹΑΓɺ௕ظʹ ΘͨΔґଘؔ܎ͷ੔߹ੑʹ͍ͭͯڧྗͳอূΛఏڙͰ͖·͢ɻϨδετϦ͸ɺಁաϩάɺ

    νΣοΫαϜ σʔλϕʔεɺ·ͨ͸ύοέʔδͷ಺༰Λೝূ͢ΔͨΊͷผͷಉ౳ͷվ͟Μ๷ࢭγεςϜΛ࣮૷͢Δ͜ ͱʹΑΓɺ͜ͷϞσϧΛ͞ΒʹվળͰ͖·͢ ɻ • ZipϑΝΠϧΛհͨ͠ύοέʔδͷ഑෍͸ɺ৽͍͠જࡏతͳ߈ܸϕΫτϧΛ΋ͨΒ͠·͢ɻͨͱ͑͹ɺ߈ ܸऀ͸ɺZip SlipͷΑ͏ͳط஌ͷ੬ऑੑɺ·ͨ͸Zipര஄ʹର͢ΔײडੑͷΑ͏ͳҰൠతͳιϑτ΢ΣΞ ͷऑ఺Λѱ༻͠Α͏ͱͯ͠ɺੜ੒͞ΕͨSource ArchiveΛѱҙΛ࣋ͬͯվ͟Μ͢ΔՄೳੑ͕͋Γ·͢ɻ • Swift Package Manager͸ɺSource Archive decompression ͷ࣮૷ʹ͓͍ͯɺ͜ΕΒͷछྨͷ߈ܸΛࣝ ผͯ͠อޢ͢ΔΑ͏ʹ஫ҙ͢Δඞཁ͕͋Γ·͢ɻ
  39. STRIDE Repudiation (൱ೝ) • ৵֐͞Εͨϗετ͸ɺ༗ޮͳνΣοΫαϜΛ࢖༻ͯ͠ѱҙͷ͋ΔύοέʔδΛఏڙ͠ɺِ଄΁ͷؔ༩Λ൱ఆ Ͱ͖ͳ͍Մೳੑ͕͋Γ·͢ɻ • ͜ͷڴҖ͸ɺόΠφϦ͓ΑͼSource Artifactʹݻ༗ͷ΋ͷͰ͢ɻGitϦϙδτϦ͸ཤྺΛ؂ࠪ͢Δ͜ͱ͕Ͱ ͖ɺݸʑͷίϛοτ͸࡞੒ऀʹΑͬͯ҉߸Ͱॺ໊͞ΕΔ৔߹͕͋Γ·͢ɻArtifactͱSource

    treeͷίϛοτ ͷؒʹ௚઀઀ଓΛཱ֬Ͱ͖ͳ͍ݶΓɺͦͷArtifactͷग़ॴΛ൑அ͢Δํ๏͸͋Γ·ͤΜɻ • Git-archive(1) ʹΑͬͯੜ੒͞ΕͨιʔεΞʔΧΠϒʹ͸HEADɺίϝϯτͱͯ͠ίϛοτͷνΣοΫαϜ͕ ؚ·Ε͍ͯ·͢ɻϓϩδΣΫτͷཤྺ͕ར༻ՄೳͰ͋ΓɺιʔεΞʔΧΠϒͷੜ੒ʹ࢖༻͞ΕΔίϛοτ͕ GPGͰॺ໊͞Ε͍ͯΔ৔߹͸ɺ҉߸Խॺ໊Λ࢖༻ͯ͠৴པੑΛݕূͰ͖·͢ • ͦΕҎ֎ͷ৔߹ɺνΣοΫαϜσʔλϕʔεͱσδλϧॺ໊ͷ࢖༻ͷ྆ํͰɺಉ༷ͷ൱ೝ๷ࢭͷอূ͕ఏڙ ͞Ε·͢ɻ
  40. $ git rev-parse HEAD b7c37c81f164e5dce0f64e3d75c79a48fb1fe00b3 $ swift package archive-source -o

    LinkedList-1.2.0.zip Generated LinkedList-1.2.0.zip $ zipnote LinkedList-1.2.0.zip | grep "@ (zip fi le comment below this line)" -A 1 | tail -n 1 b7c37c81f164e5dce0f64e3d75c79a48fb1fe00b3 $ git verify-commit b7c37c81f164e5dce0f64e3d75c79a48fb1fe00b3 gpg: Signature made Tue Dec 16 00:00:00 2020 PST gpg: using RSA key BFAA7114B920808AA4365C203C5C1CF gpg: Good signature from "Mona Lisa Octocat <[email protected]>" [ultimate]
  41. STRIDE Information disclosure (৘ใ࿙Ӯ) • Ϣʔβʔ͸ɺϓϩδΣΫτͷߏ੒ϑΝΠϧΛνΣοΫΠϯ͢Δ͜ͱʹΑΓɺޡͬͯΫϨσϯγϟϧΛެ։͢ΔՄೳੑ ͕͋Γ·͢ɻ߈ܸऀ͸ɺߏ੒ϑΝΠϧͷެ։ίʔυϦϙδτϦΛऔಘ͠ɺࢿ֨৘ใΛ࠶ར༻ͯ͠ϢʔβʔͷͳΓ͢· ͠ΛࢼΈΔՄೳੑ͕͋Γ·͢ɻ • ΫϨσϯγϟϧΛϓϩδΣΫτσΟϨΫτϦͷ֎෦ʢ௨ৗ͸ϢʔβʔͷϗʔϜσΟϨΫτϦʣʹ͋Δ.netrcϑΝΠϧ

    ʹอଘ͢Δ͜ͱͰɺ࿙Ӯ͢ΔϦεΫΛݮΒͤ·͢ɻ͔͠͠ɺϢʔβʔ͸swift packageίϚϯυʹ —netrc- fi leΦϓ γϣϯΛ͚ͭΔ͜ͱͰɺϓϩδΣΫτͷ.netrcϑΝΠϧΛࢦఆ͢Δ͔΋͠Ε·ͤΜɻ͜ͷϦεΫΛܰݮ͢ΔͨΊʹɺ swift package initͰϓϩδΣΫτΛ࡞੒͢Δͱ͖ʹ.gitignoreʹ.netrcΛ௥Ճ͠·͢ɻ • ϗεςΟϯάϓϩόΠμ͸Public repositoryʹίϛοτ͞Ε͍ͯΔsecretΛݕग़͢Δ͜ͱʹΑΓɺ͜ͷϦεΫΛ࠷খ ݶʹ཈͑Δ͜ͱ͕Ͱ͖·͢ • ΫϨσϯγϟϧ͸Swift PM΍ଞͷπʔϧͷϩάͰҙਤͤͣ։ࣔ͞ΕΔ͜ͱ͕͋Γ·͢ɻදࣔ͞ΕΔࡍ͸ɺϢʔβʔ໊ ΍ύεϫʔυΛฤूͯ͠ݟͤͳ͍Α͏ʹ͢Δඞཁ͕͋Γ·͢ɻ
  42. STRIDE Denial of Service (αʔϏεڋ൱) • ߈ܸऀ͸ΧελϜϨδετϦΛఆٛ͢Δ .swiftpm/con fi guration/registires.jsonΛεΫϨΠϐϯά͠ɺͦ

    ͷϦιʔεͷՄ༻ੑΛ௿Լͤ͞ΔαʔϏεڋ൱߈ܸΛߦ͏Մೳੑ͕͋Γ·͢ɻ • Ұൠతʹɺ͜ͷ߈ܸͷՄೳੑ͸௿͍Ͱ͕͢ɺॏཁੑ͕ߴ͘ɺίετ͕͔͔ΔϦιʔεʹରͯ͠తΛߜͬ ͯ͘ΔՄೳੑ͕ߟ͑ΒΕ·͢ɻ • ͜ͷछྨͷ߈ܸ͸ɺ.gitignoreʹ .swiftpm/con fi gurationΛ௥Ճ͢Δ͜ͱͰܰݮͰ͖·͢ɻ