{"id":612,"date":"2023-08-22T11:15:32","date_gmt":"2023-08-22T18:15:32","guid":{"rendered":"https:\/\/downthecrop.xyz\/blog\/?p=612"},"modified":"2023-08-26T10:09:32","modified_gmt":"2023-08-26T17:09:32","slug":"macos-ci-cd-artifacts","status":"publish","type":"post","link":"https:\/\/downthecrop.xyz\/blog\/macos-ci-cd-artifacts\/","title":{"rendered":"CI\/CD macOS Application Bundling .app Artifacts"},"content":{"rendered":"<h1>CI\/CD macOS Application Bundling .app Artifacts<\/h1>\n<h4>1. macOS Application Bundle Structure<\/h4>\n<h5>1.1 The <code>.app<\/code> Bundle Format<\/h5>\n<p>In macOS, applications are distributed as bundles, a directory structure that contains executable code and related resources. Here's the typical structure of a <code>.app<\/code> bundle:<\/p>\n<pre><code>MyApp.app\/\n  Contents\/\n    Info.plist\n    MacOS\/\n      MyApp\n    Resources\/\n      MyApp.icns<\/code><\/pre>\n<ul>\n<li><code>Info.plist<\/code>:  Metadata and configuration information.<\/li>\n<li><code>MacOS\/<\/code>:  Main executable file.<\/li>\n<li><code>Resources\/<\/code>: Stores resource files, such as images and localized content.<\/li>\n<\/ul>\n<h5>1.2 Understanding the Info.plist File<\/h5>\n<p>A <code>.app<\/code> bundle is really just a directory. The <code>Info.plist<\/code> file is critical to the <code>.app<\/code> bundle as it is what defines how to use this folder as a launcher instead of a folder. It contains key-value pairs that macOS uses to index the application. Key elements include:<\/p>\n<ul>\n<li><code>CFBundleExecutable<\/code>: Specifies the main executable file.<\/li>\n<li><code>CFBundleIconFile<\/code>: Defines the icon file.<\/li>\n<\/ul>\n<p>Here's an example snippet:<\/p>\n<pre><code class=\"language-xml\">&lt;dict&gt;\n    &lt;key&gt;CFBundleExecutable&lt;\/key&gt;\n    &lt;string&gt;MyApp&lt;\/string&gt;\n    &lt;key&gt;CFBundleIconFile&lt;\/key&gt;\n    &lt;string&gt;MyApp.icns&lt;\/string&gt;\n&lt;\/dict&gt;<\/code><\/pre>\n<h4>2. ICNS Conversion<\/h4>\n<p>macOS uses the ICNS file format for icons. A convenient conversion tool is <a href=\"https:\/\/github.com\/molcik\/png-to-icns-right-click-converter\">png-to-icns-right-click-converter<\/a>. This tool allows for seamless conversion from PNG to ICNS, suitable for inclusion in the application bundle's Resources directory.<\/p>\n<h4>3. CI\/CD Integration<\/h4>\n<h5>3.1 YAML Configuration for Packaging macOS Application<\/h5>\n<p>Continuous Integration and Continuous Deployment (CI\/CD) streamline the development workflow. Below is a YAML script that demonstrates how to package a macOS application binary:<\/p>\n<pre><code class=\"language-yaml\">pack_macos_app:\n    stage: package_stage\n    dependencies:\n        - build_stage\n    script:\n        - INFO_PLIST=&quot;$APP_NAME.app\/Contents\/Info.plist&quot;\n        - echo &quot;Packing self-contained build for macOS x64...&quot;\n        - mkdir -p $APP_NAME.app\/Contents\/MacOS\n        - mkdir -p $APP_NAME.app\/Contents\/Resources\n        - cp Resources\/Icons\/icon.icns $APP_NAME.app\/Contents\/Resources\/\n        - cp $BUILD_DIR\/$BINARY_NAME $APP_NAME.app\/Contents\/MacOS\/\n        - chmod +x $APP_NAME.app\/Contents\/MacOS\/$BINARY_NAME\n        - echo &#039;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#039; &gt; $INFO_PLIST\n        - echo &#039;&lt;!DOCTYPE plist PUBLIC &quot;-\/\/Apple\/\/DTD PLIST 1.0\/\/EN&quot; &quot;http:\/\/www.apple.com\/DTDs\/PropertyList-1.0.dtd&quot;&gt;&#039; &gt;&gt; $INFO_PLIST\n        - echo &#039;&lt;plist version=&quot;1.0&quot;&gt;&#039; &gt;&gt; $INFO_PLIST\n        - echo &#039;&lt;dict&gt;&#039; &gt;&gt; $INFO_PLIST\n        - echo &#039;    &lt;key&gt;CFBundleExecutable&lt;\/key&gt;&#039; &gt;&gt; $INFO_PLIST\n        - echo &quot;    &lt;string&gt;$BINARY_NAME&lt;\/string&gt;&quot; &gt;&gt; $INFO_PLIST\n        - echo &#039;    &lt;key&gt;CFBundleIconFile&lt;\/key&gt;&#039; &gt;&gt; $INFO_PLIST\n        - echo &#039;    &lt;string&gt;icon.icns&lt;\/string&gt;&#039; &gt;&gt; $INFO_PLIST\n        - echo &#039;&lt;\/dict&gt;&#039; &gt;&gt; $INFO_PLIST\n        - echo &#039;&lt;\/plist&gt;&#039; &gt;&gt; $INFO_PLIST\n    artifacts:\n        name: &quot;macOS x64 (self-contained)&quot;\n        paths:\n            - $BUILD_DIR\/$APP_NAME.app\n        expire_in: 1 week<\/code><\/pre>\n<h3>TL;DR<\/h3>\n<p>macOS applications rely on a bundle structure, where an application is organized as a directory with the .app extension. This structure includes executable code, resources, and metadata, all defined within specific subdirectories and files such as .plist and ICNS icon files. Understanding these aspects allows developers to create CI\/CD bundling stages for any macOS app.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>CI\/CD macOS Application Bundling .app Artifacts 1. macOS Application Bundle Structure 1.1 The .app Bundle Format In macOS, applications are distributed as bundles, a directory structure that contains executable code and related resources. Here&#8217;s the typical structure of a .app bundle: MyApp.app\/ Contents\/ Info.plist MacOS\/ MyApp Resources\/ MyApp.icns Info.plist: Metadata and configuration information. MacOS\/: Main &hellip; <a href=\"https:\/\/downthecrop.xyz\/blog\/macos-ci-cd-artifacts\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">CI\/CD macOS Application Bundling .app Artifacts<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"amp_validity":null,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/posts\/612"}],"collection":[{"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/comments?post=612"}],"version-history":[{"count":2,"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/posts\/612\/revisions"}],"predecessor-version":[{"id":630,"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/posts\/612\/revisions\/630"}],"wp:attachment":[{"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/media?parent=612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/categories?post=612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/downthecrop.xyz\/blog\/wp-json\/wp\/v2\/tags?post=612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}