{"action":"created","comment":{"url":"https://api.github.com/repos/roots/trellis/pulls/comments/92322334","pull_request_review_id":12835021,"id":92322334,"diff_hunk":"@@ -2,25 +2,41 @@\n - include: \"{{ deploy_share_before | default('../hooks/example.yml') }}\"\n   tags: deploy-share-before\n \n-- name: Ensure shared sources are present\n+- name: Ensure shared sources are present -- directories\n+  file:\n+    path: \"{{ deploy_helper.shared_path }}/{{ project_shared_file | ternary(item.src | dirname, item.src) }}\"\n+    state: \"{{ project_shared_file | ternary('directory', item.type | default('directory')) | lower }}\"\n+    mode: \"{{ project_shared_file | ternary('0755', item.mode | default('0755')) }}\"\n+  with_items: \"{{ project_shared_children }}\"\n+\n+- name: Ensure shared sources are present -- files\n   file:\n     path: \"{{ deploy_helper.shared_path }}/{{ item.src }}\"\n-    state: \"{{ item.type | default('directory') }}\"\n-    mode: \"{{ item.mode | default('0755') }}\"\n+    state: touch\n+    mode: \"{{ item.mode | default('0644') }}\"\n+  with_items: \"{{ project_shared_children }}\"\n+  when: project_shared_file\n+\n+- name: Ensure parent directories for shared paths are present\n+  file:\n+    path: \"{{ deploy_helper.new_release_path }}/{{ item.path | default('') | dirname }}\"\n+    state: directory\n   with_items: \"{{ project_shared_children }}\"\n \n - name: Ensure shared paths are absent\n   file:\n-    path: \"{{ deploy_helper.new_release_path }}/{{ item.path }}\"\n+    path: \"{{ deploy_helper.new_release_path }}/{{ item.path  | default('') }}\"\n     state: absent\n   with_items: \"{{ project_shared_children }}\"\n+  when: item.type | default('directory') | lower != 'absent'\n \n - name: Create shared symlinks\n   file:\n-    path: \"{{ deploy_helper.new_release_path }}/{{ item.path }}\"\n+    path: \"{{ deploy_helper.new_release_path }}/{{ item.path | default('') }}\"","path":"roles/deploy/tasks/share.yml","position":39,"original_position":39,"commit_id":"4cedc080b1504930a6ac57da8a232a82a4281d6e","original_commit_id":"4cedc080b1504930a6ac57da8a232a82a4281d6e","user":{"login":"fullyint","id":7338513,"avatar_url":"https://avatars.githubusercontent.com/u/7338513?v=3","gravatar_id":"","url":"https://api.github.com/users/fullyint","html_url":"https://github.com/fullyint","followers_url":"https://api.github.com/users/fullyint/followers","following_url":"https://api.github.com/users/fullyint/following{/other_user}","gists_url":"https://api.github.com/users/fullyint/gists{/gist_id}","starred_url":"https://api.github.com/users/fullyint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fullyint/subscriptions","organizations_url":"https://api.github.com/users/fullyint/orgs","repos_url":"https://api.github.com/users/fullyint/repos","events_url":"https://api.github.com/users/fullyint/events{/privacy}","received_events_url":"https://api.github.com/users/fullyint/received_events","type":"User","site_admin":false},"body":"The `absent` option allows an easy way for someone to remove something from `/shared` if it will no longer be used in the next deployment(s). Although it is not necessary to remove items, and although people could remove them manually, facilitating this `absent` option requires no extra tasks, so I thought it was convenient.\r\n\r\nHowever, the `absent` option does require the the two tasks you've marked to include `when` conditions and `item.path | default('')`. Yes these two tasks will skip for items set to `absent`, but Ansible still attempts to template all the variables in the task. So, without a default for `item.path`, the task would fail when people omit `path` for items set to `absent`. \r\n\r\nIf we keep this `absent` option, I would like people to be able to omit `path` because an item to be removed from `/shared` will have no `path` in the release directory, so the `path` parameter doesn't make sense to include.","created_at":"2016-12-14T04:52:02Z","updated_at":"2016-12-14T04:52:02Z","html_url":"https://github.com/roots/trellis/pull/706#discussion_r92322334","pull_request_url":"https://api.github.com/repos/roots/trellis/pulls/706","_links":{"self":{"href":"https://api.github.com/repos/roots/trellis/pulls/comments/92322334"},"html":{"href":"https://github.com/roots/trellis/pull/706#discussion_r92322334"},"pull_request":{"href":"https://api.github.com/repos/roots/trellis/pulls/706"}}},"pull_request":{"url":"https://api.github.com/repos/roots/trellis/pulls/706","id":97410668,"html_url":"https://github.com/roots/trellis/pull/706","diff_url":"https://github.com/roots/trellis/pull/706.diff","patch_url":"https://github.com/roots/trellis/pull/706.patch","issue_url":"https://api.github.com/repos/roots/trellis/issues/706","number":706,"state":"open","locked":false,"title":"Create project_shared_children files if they do not exist","user":{"login":"fullyint","id":7338513,"avatar_url":"https://avatars.githubusercontent.com/u/7338513?v=3","gravatar_id":"","url":"https://api.github.com/users/fullyint","html_url":"https://github.com/fullyint","followers_url":"https://api.github.com/users/fullyint/followers","following_url":"https://api.github.com/users/fullyint/following{/other_user}","gists_url":"https://api.github.com/users/fullyint/gists{/gist_id}","starred_url":"https://api.github.com/users/fullyint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fullyint/subscriptions","organizations_url":"https://api.github.com/users/fullyint/orgs","repos_url":"https://api.github.com/users/fullyint/repos","events_url":"https://api.github.com/users/fullyint/events{/privacy}","received_events_url":"https://api.github.com/users/fullyint/received_events","type":"User","site_admin":false},"body":"Fixes this [discourse thread](https://discourse.roots.io/t/create-symlinks-for-files/7086).\r\n\r\nThe \"[Ensure shared sources are present](https://github.com/roots/trellis/blob/8453c53213eb722e5293dded8cceff3ebf33a493/roles/deploy/tasks/share.yml#L5-L10)\" task uses the [file module](http://docs.ansible.com/ansible/file_module.html) to create directories or files in the `shared` directory.\r\n\r\nThe [comments for `project_shared_children`](https://github.com/roots/trellis/blob/8453c53213eb722e5293dded8cceff3ebf33a493/roles/deploy/defaults/main.yml#L25) in the deploy/defaults indicates that items in the list \"are created if they don't exist.\" The problem is that if a user specifies `type: file`, this is fed to the `state` option for the file module, but when `state` is \"`file`, the file will NOT be created if it does not exist.\" \r\n\r\nIn addition, the file module will not create the subdirectories a file may be in, if they are missing. \r\n\r\nThis PR splits the \"Ensure shared sources are present\" task in two. The first task creates all the shared directories, including the parent directories of shared files. The second task touches the files.\r\n> If `touch` (new in 1.4), an empty file will be created if the `path` does not exist, while an existing file or directory will receive updated file access and modification times  [-- ref](http://docs.ansible.com/ansible/file_module.html) \r\n\r\nTouch is necessary if we actually want to create files, but unfortunately it is never idempotent.\r\n\r\nThis approach should still allow for `type`/`state` values such as `absent`.","created_at":"2016-12-10T02:55:46Z","updated_at":"2016-12-14T04:52:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c4a0e0d92926deab757ce7a64869f1fffd968221","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/roots/trellis/pulls/706/commits","review_comments_url":"https://api.github.com/repos/roots/trellis/pulls/706/comments","review_comment_url":"https://api.github.com/repos/roots/trellis/pulls/comments{/number}","comments_url":"https://api.github.com/repos/roots/trellis/issues/706/comments","statuses_url":"https://api.github.com/repos/roots/trellis/statuses/4cedc080b1504930a6ac57da8a232a82a4281d6e","head":{"label":"roots:project-shared-children","ref":"project-shared-children","sha":"4cedc080b1504930a6ac57da8a232a82a4281d6e","user":{"login":"roots","id":4986074,"avatar_url":"https://avatars.githubusercontent.com/u/4986074?v=3","gravatar_id":"","url":"https://api.github.com/users/roots","html_url":"https://github.com/roots","followers_url":"https://api.github.com/users/roots/followers","following_url":"https://api.github.com/users/roots/following{/other_user}","gists_url":"https://api.github.com/users/roots/gists{/gist_id}","starred_url":"https://api.github.com/users/roots/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roots/subscriptions","organizations_url":"https://api.github.com/users/roots/orgs","repos_url":"https://api.github.com/users/roots/repos","events_url":"https://api.github.com/users/roots/events{/privacy}","received_events_url":"https://api.github.com/users/roots/received_events","type":"Organization","site_admin":false},"repo":{"id":18852165,"name":"trellis","full_name":"roots/trellis","owner":{"login":"roots","id":4986074,"avatar_url":"https://avatars.githubusercontent.com/u/4986074?v=3","gravatar_id":"","url":"https://api.github.com/users/roots","html_url":"https://github.com/roots","followers_url":"https://api.github.com/users/roots/followers","following_url":"https://api.github.com/users/roots/following{/other_user}","gists_url":"https://api.github.com/users/roots/gists{/gist_id}","starred_url":"https://api.github.com/users/roots/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roots/subscriptions","organizations_url":"https://api.github.com/users/roots/orgs","repos_url":"https://api.github.com/users/roots/repos","events_url":"https://api.github.com/users/roots/events{/privacy}","received_events_url":"https://api.github.com/users/roots/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/roots/trellis","description":"Ansible playbooks for a WordPress LEMP stack","fork":false,"url":"https://api.github.com/repos/roots/trellis","forks_url":"https://api.github.com/repos/roots/trellis/forks","keys_url":"https://api.github.com/repos/roots/trellis/keys{/key_id}","collaborators_url":"https://api.github.com/repos/roots/trellis/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/roots/trellis/teams","hooks_url":"https://api.github.com/repos/roots/trellis/hooks","issue_events_url":"https://api.github.com/repos/roots/trellis/issues/events{/number}","events_url":"https://api.github.com/repos/roots/trellis/events","assignees_url":"https://api.github.com/repos/roots/trellis/assignees{/user}","branches_url":"https://api.github.com/repos/roots/trellis/branches{/branch}","tags_url":"https://api.github.com/repos/roots/trellis/tags","blobs_url":"https://api.github.com/repos/roots/trellis/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/roots/trellis/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/roots/trellis/git/refs{/sha}","trees_url":"https://api.github.com/repos/roots/trellis/git/trees{/sha}","statuses_url":"https://api.github.com/repos/roots/trellis/statuses/{sha}","languages_url":"https://api.github.com/repos/roots/trellis/languages","stargazers_url":"https://api.github.com/repos/roots/trellis/stargazers","contributors_url":"https://api.github.com/repos/roots/trellis/contributors","subscribers_url":"https://api.github.com/repos/roots/trellis/subscribers","subscription_url":"https://api.github.com/repos/roots/trellis/subscription","commits_url":"https://api.github.com/repos/roots/trellis/commits{/sha}","git_commits_url":"https://api.github.com/repos/roots/trellis/git/commits{/sha}","comments_url":"https://api.github.com/repos/roots/trellis/comments{/number}","issue_comment_url":"https://api.github.com/repos/roots/trellis/issues/comments{/number}","contents_url":"https://api.github.com/repos/roots/trellis/contents/{+path}","compare_url":"https://api.github.com/repos/roots/trellis/compare/{base}...{head}","merges_url":"https://api.github.com/repos/roots/trellis/merges","archive_url":"https://api.github.com/repos/roots/trellis/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/roots/trellis/downloads","issues_url":"https://api.github.com/repos/roots/trellis/issues{/number}","pulls_url":"https://api.github.com/repos/roots/trellis/pulls{/number}","milestones_url":"https://api.github.com/repos/roots/trellis/milestones{/number}","notifications_url":"https://api.github.com/repos/roots/trellis/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/roots/trellis/labels{/name}","releases_url":"https://api.github.com/repos/roots/trellis/releases{/id}","deployments_url":"https://api.github.com/repos/roots/trellis/deployments","created_at":"2014-04-16T19:08:33Z","updated_at":"2016-12-13T19:17:33Z","pushed_at":"2016-12-14T01:50:16Z","git_url":"git://github.com/roots/trellis.git","ssh_url":"git@github.com:roots/trellis.git","clone_url":"https://github.com/roots/trellis.git","svn_url":"https://github.com/roots/trellis","homepage":"https://roots.io/trellis/","size":811,"stargazers_count":1224,"watchers_count":1224,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":354,"mirror_url":null,"open_issues_count":27,"forks":354,"open_issues":27,"watchers":1224,"default_branch":"master"}},"base":{"label":"roots:master","ref":"master","sha":"8453c53213eb722e5293dded8cceff3ebf33a493","user":{"login":"roots","id":4986074,"avatar_url":"https://avatars.githubusercontent.com/u/4986074?v=3","gravatar_id":"","url":"https://api.github.com/users/roots","html_url":"https://github.com/roots","followers_url":"https://api.github.com/users/roots/followers","following_url":"https://api.github.com/users/roots/following{/other_user}","gists_url":"https://api.github.com/users/roots/gists{/gist_id}","starred_url":"https://api.github.com/users/roots/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roots/subscriptions","organizations_url":"https://api.github.com/users/roots/orgs","repos_url":"https://api.github.com/users/roots/repos","events_url":"https://api.github.com/users/roots/events{/privacy}","received_events_url":"https://api.github.com/users/roots/received_events","type":"Organization","site_admin":false},"repo":{"id":18852165,"name":"trellis","full_name":"roots/trellis","owner":{"login":"roots","id":4986074,"avatar_url":"https://avatars.githubusercontent.com/u/4986074?v=3","gravatar_id":"","url":"https://api.github.com/users/roots","html_url":"https://github.com/roots","followers_url":"https://api.github.com/users/roots/followers","following_url":"https://api.github.com/users/roots/following{/other_user}","gists_url":"https://api.github.com/users/roots/gists{/gist_id}","starred_url":"https://api.github.com/users/roots/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roots/subscriptions","organizations_url":"https://api.github.com/users/roots/orgs","repos_url":"https://api.github.com/users/roots/repos","events_url":"https://api.github.com/users/roots/events{/privacy}","received_events_url":"https://api.github.com/users/roots/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/roots/trellis","description":"Ansible playbooks for a WordPress LEMP stack","fork":false,"url":"https://api.github.com/repos/roots/trellis","forks_url":"https://api.github.com/repos/roots/trellis/forks","keys_url":"https://api.github.com/repos/roots/trellis/keys{/key_id}","collaborators_url":"https://api.github.com/repos/roots/trellis/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/roots/trellis/teams","hooks_url":"https://api.github.com/repos/roots/trellis/hooks","issue_events_url":"https://api.github.com/repos/roots/trellis/issues/events{/number}","events_url":"https://api.github.com/repos/roots/trellis/events","assignees_url":"https://api.github.com/repos/roots/trellis/assignees{/user}","branches_url":"https://api.github.com/repos/roots/trellis/branches{/branch}","tags_url":"https://api.github.com/repos/roots/trellis/tags","blobs_url":"https://api.github.com/repos/roots/trellis/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/roots/trellis/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/roots/trellis/git/refs{/sha}","trees_url":"https://api.github.com/repos/roots/trellis/git/trees{/sha}","statuses_url":"https://api.github.com/repos/roots/trellis/statuses/{sha}","languages_url":"https://api.github.com/repos/roots/trellis/languages","stargazers_url":"https://api.github.com/repos/roots/trellis/stargazers","contributors_url":"https://api.github.com/repos/roots/trellis/contributors","subscribers_url":"https://api.github.com/repos/roots/trellis/subscribers","subscription_url":"https://api.github.com/repos/roots/trellis/subscription","commits_url":"https://api.github.com/repos/roots/trellis/commits{/sha}","git_commits_url":"https://api.github.com/repos/roots/trellis/git/commits{/sha}","comments_url":"https://api.github.com/repos/roots/trellis/comments{/number}","issue_comment_url":"https://api.github.com/repos/roots/trellis/issues/comments{/number}","contents_url":"https://api.github.com/repos/roots/trellis/contents/{+path}","compare_url":"https://api.github.com/repos/roots/trellis/compare/{base}...{head}","merges_url":"https://api.github.com/repos/roots/trellis/merges","archive_url":"https://api.github.com/repos/roots/trellis/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/roots/trellis/downloads","issues_url":"https://api.github.com/repos/roots/trellis/issues{/number}","pulls_url":"https://api.github.com/repos/roots/trellis/pulls{/number}","milestones_url":"https://api.github.com/repos/roots/trellis/milestones{/number}","notifications_url":"https://api.github.com/repos/roots/trellis/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/roots/trellis/labels{/name}","releases_url":"https://api.github.com/repos/roots/trellis/releases{/id}","deployments_url":"https://api.github.com/repos/roots/trellis/deployments","created_at":"2014-04-16T19:08:33Z","updated_at":"2016-12-13T19:17:33Z","pushed_at":"2016-12-14T01:50:16Z","git_url":"git://github.com/roots/trellis.git","ssh_url":"git@github.com:roots/trellis.git","clone_url":"https://github.com/roots/trellis.git","svn_url":"https://github.com/roots/trellis","homepage":"https://roots.io/trellis/","size":811,"stargazers_count":1224,"watchers_count":1224,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":354,"mirror_url":null,"open_issues_count":27,"forks":354,"open_issues":27,"watchers":1224,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/roots/trellis/pulls/706"},"html":{"href":"https://github.com/roots/trellis/pull/706"},"issue":{"href":"https://api.github.com/repos/roots/trellis/issues/706"},"comments":{"href":"https://api.github.com/repos/roots/trellis/issues/706/comments"},"review_comments":{"href":"https://api.github.com/repos/roots/trellis/pulls/706/comments"},"review_comment":{"href":"https://api.github.com/repos/roots/trellis/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/roots/trellis/pulls/706/commits"},"statuses":{"href":"https://api.github.com/repos/roots/trellis/statuses/4cedc080b1504930a6ac57da8a232a82a4281d6e"}}}}
{"actor":{"display_login":"fullyint"}}